// page init
var user_agent = navigator.userAgent;

var is_safari_mac = (user_agent.indexOf('Safari') > -1) && (user_agent.indexOf('Mac') > -1);
var safari_version = 0;

if(is_safari_mac)
{
  var re = new RegExp(/.*Version\/([0-9])\..*/gi);
  var match = re.exec(user_agent);
  if(match!=null)
    safari_version = match[1];
}

jQuery(function () {
    initNavIndexes();
    initInputs();
    jcf.customForms.replaceAll();
    initSelectLine();
    //init_fancybox();

    // Calendar
    if ($('#calendar').length > 0)
    {
        $("#calendar").datepicker({
            dayNamesMin: ["S", "M", "T", "W", "T", "F", "S"],
            showOtherMonths: true
        });
    }

  // Tooltips
  $('.info').tooltip({
    showURL: false,
    track: true,
    fade: 150,
    top: 23, 
    left: 0
  }).css('cursor', 'pointer');

  $('.count-tooltip').tooltip({
      showURL: false,
      track: true,
      fade: 150,
      top: -100,
      left: -380,
      bodyHandler: function () {
          $('#tooltip').addClass('count-tooltip-wrapper');
          return $(this).find('.tooltip-simpletable').clone();
      }
  }).css('cursor', 'pointer');

  // Dashboard calendar
  if ($('#calendar').length > 0) {
      $("#calendar").datepicker({
          dayNamesMin: ["S", "M", "T", "W", "T", "F", "S"],
          showOtherMonths: true
      });
  }

  //Horizontal scroll
  //hscroll_size();
  //$(window).resize(hscroll_size);

  // Resize textbox inside table
  $('.textintable').each(function () {
      var i = $(this);
      i.width(get_width_only(i.parent()))
     .width(get_width_only(i));
  });

  // Progress bar fix
  //resize_progress_bar();
  //$(window).resize(resize_progress_bar);

  // show more options
  $('.col1.error').showMoreOptions();

  $('.title .col1:last').css('border-right', 'none');
  $('.line').each(function () {
      $(this).find('.col1:last').css('border-right', 'none');
  });


  // Editable select
  init_editable_select();

  //normalize_cols_height($('.table-leads'));
  //contents height
  //content_max_height($('.dashboard'));
  //content_max_height($('.leads-view'));

    //Horizontal scroll
  hscroll_size();
  hscroll_resize_events();
  $(window).resize(hscroll_size);
  $(window).resize(hscroll_resize_events);
  
  // Disabler
  /*$('#toolbar1, #grouped-form1').disabler();
  // Filters init
  $('.filter-trigger').showFilter();*/

  $('.toolbar .filters a[href=#]').click(function () { return false; });

  $('.search .searchbox').each(function(id, el){
    var el = $(el);
    var field_pos = el.offset();
    
    var xbtn = $('<a href="#" class="btn btn-gray-x btn-clearsearch">Clear</a>').
      css({
        position: 'absolute',
        zIndex: 98,
        top: 2, //field_pos['top'] + ((el.outerHeight(true) - 25) / 2) + 5,
        right: 11//field_pos['left'] + el.outerWidth(true) - 20
      });
      
    xbtn.search_field = el;

    xbtn.click(function(){
      el.val('').focus();
    });
    
//    $(window).bind('resize', function(){
//      var field_pos = xbtn.search_field.offset();
//      xbtn.css({
//        top: field_pos['top'] + ((xbtn.search_field.outerHeight(true) - 25) / 2) + 5,
//        left: field_pos['left'] + xbtn.search_field.outerWidth(true) - 20
//      })
//    });

    $('#headerSearchInput').append(xbtn);
  });
    
    $('input[type=text].search').each(function(id, el){
        var el = $(el);
        var field_pos = el.offset();
    
        var xbtn = $('<a href="#" class="btn btn-gray-x btn-clearsearch">Clear</a>').
            css({
            position: 'absolute',
            zIndex: 98,
            top: 1, 
            right: 7
            });
      
        xbtn.search_field = el;

        xbtn.click(function(){
            el.val('').focus();
        });

        $('#SearchInput').append(xbtn);
    });
  
  $('#row-sel-subindustry').hide();
  $('#sel-industry').change(function(){
    var i = $(this);
    
    var req = $.post("ajax.php", { industry: i.val() }, null, 'json');
    
    req.success(function(data){
      $('#row-sel-subindustry').hide();
      $("#sel-subindustry").html('');
      $("#sel-subindustry").append($('<option />').attr('id', '').html('Select Sub-Industry'));
      
      var has_data = false;
      $(data).each(function(id, el){
        has_data = true;
        $("#sel-subindustry").append($('<option />').attr('id', el.id).html(el.name));
      });
      
      if(has_data) $('#row-sel-subindustry').fadeIn(300);
      
      //refresh JCF
			var els = jcf.lib.queryBySelector(jcf.modules['select'].prototype.selector);
			for(var i = 0; i<els.length; i++) {
				if(els[i].jcf) {
					els[i].jcf.buildDropdownOptions();
					els[i].jcf.refreshState();
				}
			}
			
    });
  });
  
  //CSS Fixes
  if(is_safari_mac){
    $('.toolbar .select-holder').css({marginBottom: '3px'});
    $('.toolbar input.editable-select').css({height: '24px'});
  }
});


$.fn.set_action_tooltip = function(opt) {
  var defaults = {  
    width: 300,
    offset_x: 0,
    offset_y: 0,
    cancel_class: '',
    continue_class: '',
    
  };  
  var opt = $.extend(defaults, opt);
  var el = $(this);

  el.click(function(){
    var i = $(this);
    var msg = i.attr('title');
    if(!msg) return false;
    
    var btn_pos = i.offset();
    
    
    if($('.action-tooltip').length == 0)
    {      
      var ttip = $('<div/>').addClass('action-tooltip').hide();
      $('body').append(ttip);
      ttip.append('<h4>'+msg+'</h4>')
          .append('<a href="#" class="'+ opt.cancel_class +' act-cancel">Cancel</a>')
          .append('<a href="#" class="'+ opt.continue_class +' act-continue">Continue</a>')
          .append('<span class="arr" />')
          .css({width: opt.width})
          .css({
            top: (btn_pos['top']  - ttip.outerHeight(true) + opt.offset_y),
            left: (btn_pos['left'] - ttip.outerWidth(true) + i.outerWidth(true) + opt.offset_x)
          });
      
      ttip.find('.act-cancel').click(function(){
        ttip.fadeOut(300);
        return false;
      });
      ttip.find('.act-continue').click(function(){
        // Delete an appointment
        // Using knockout
        editLeadViewModel.DeleteAppointment();
        ttip.fadeOut(300);
        return false;
      });
    }
    else
    {
      var ttip = $('.action-tooltip').hide();
      ttip.find('h4').html(msg);
      ttip.css({
        top: (btn_pos['top']  - ttip.outerHeight(true) + opt.offset_y),
        left: (btn_pos['left'] - ttip.outerWidth(true) + i.outerWidth(true) + opt.offset_x)
      });
    }
    
    ttip.fadeIn(300);
    return false;    
    
  });
  
  
  //CSS Fixes
  if(is_safari_mac){
    $('.toolbar .select-holder').css({marginBottom: '3px'});
    $('.toolbar input.editable-select').css({height: '24px'});
  }
  
};

function resize_progress_bar(){
  var pb = $('progress-bar');
  pb.width(
    pb.parent().width() - pb.parent().find('.progress-info').width() - 20
  );    
}



var parent_extra_sum = 0;

function hscroll_size(){

  //console.log('**************************************');
  
  // Sum cols width and set it as .title and .line widths
  /*
  var sum=0; 
  $('.table-horscroll .line:first').children().each( function(){ 
    sum += $(this).Outerwidth(true)
  });
  $('.table-horscroll .title').width(sum+10);
  $('.table-horscroll .line').width(sum+10);
  */

  // If NOT full width layout then return
  if($('.full-width').length==0) return;
  
  var ths = $('.table-horscroll'); // scrollable table
  var ths_parent = ths.parent();
  var viewport_w = $(window).width(); // Viewport or window width
  var parent_w = ths_parent.width() - 1; // Table parent width
  var min_w = parseInt($('.full-width').css("min-width"), 10); // Document min-width set for .full-width (liquid) pages
  
  // Go up from the table to the root element getting borders, paddings and margins
  //var tmp_sum = 0; // sum

  if(parent_extra_sum == 0)
  {
    var tmp_t = ths_parent; // copy of ths_parent element
    
    while(tmp_t.parent().length>0)
    {
      //parent_extra_sum += sum_width_extras( tmp_t );
      parent_extra_sum += (tmp_t.outerWidth(true) - tmp_t.width());
      tmp_t = tmp_t.parent();
    }
    
    parent_extra_sum += sum_width_extras( ths ) + 2;
    //parent_extra_sum += (ths.outerWidth(true) - ths.width()) + 2;
  }
  var tmp_sum = parent_extra_sum;
  //console.log('tmp_sum: '+tmp_sum);

  // Detects wether there's scroll by comparising viewport/doc widths
  var it_scrolls = $(window).height() < $(document).height();
  //if(it_scrolls)console.log('it_scrolls');

  var parents_based_width = parent_w - sum_width_extras( ths );
  //var parents_based_width = parent_w - (ths.outerWidth(true) - ths.width());
  //console.log('parents_based_width: '+parents_based_width);
  
  // If it scroll and is not mac safari (floating scroll), sum scroll width.
  if(it_scrolls && !(is_safari_mac && safari_version >= 6)){
    tmp_sum += 17;
  }
  
  //console.log('tmp_sum: ' + tmp_sum);
  //console.log('viewport_w: ' + viewport_w);
    
  var vp_based_width = viewport_w - tmp_sum;
  //console.log('vp_based_width: ' + vp_based_width);
  
  if( vp_based_width<=990 ) vp_based_width = 990;
  
  //console.log('vp_based_width: ' + vp_based_width);
  ths.width(vp_based_width + 2);
}

function hscroll_resize_events(){

  var ths = $('.shortdesc');
  var viewport_w = $(window).width();   
  //console.log('window: ' + viewport_w);
  var vp_based_width = viewport_w - 825;
  if( vp_based_width<= 270 ) vp_based_width = 270;
  
  //console.log('short_based_width: ' + vp_based_width);
  ths.width(vp_based_width);
}


function get_width_only(el){
  var w = el.width() - 
    parseInt(el.css("margin-left"), 10) - 
    parseInt(el.css("margin-right"), 10) - 
    parseInt(el.css("padding-left"), 10) - 
    parseInt(el.css("padding-right"), 10) - 
    parseInt(el.css("border-left-width"), 10) - 
    parseInt(el.css("border-right-width"), 10);
    
  return w;
}

function sum_width_extras( el ){
  var tmp_s = parseInt(el.css("padding-left"), 10) + parseInt(el.css("padding-right"), 10) + 
    parseInt(el.css("margin-left"), 10) + parseInt(el.css("margin-right"), 10) + 
    parseInt(el.css("borderLeftWidth"), 10) + parseInt(el.css("borderRightWidth"), 10);
  return tmp_s;
}

function init_editable_select(){
  if(!$('.editable-select').length) return;

  $('.editable-select').editableSelect({
    bg_iframe: true,
    case_sensitive: false,
    items_then_scroll: 10
  });
}

$.fn.showPopup = function(opt) {
  var defaults = {  
    width: 400,
    opacity: 0.6,
    overlayColor: '#11619d',
    padding: 0,
    closeButton: false
  };  
  var opt = $.extend(defaults, opt);
  
  var i = $(this);
  
  $(document).ready(function()
  {  
    $.fancybox(i,
    {
      padding: opt.padding,
      closeBtn: opt.closeButton,
      width: opt.width,
      minWidth: opt.width,
      maxWidth: opt.width,
      helpers : {
        overlay : {
            opacity: opt.opacity,
            css : {
                'background-color' : opt.overlayColor
            }
        }
      },
      beforeClose: function(){
        if(!opt.closeButton)
          return false;
      }
    });
  });
};

$.fn.showMoreOptions = function() {
  var mouse_is_inside = false;
  
  var i = $(this);
  
  var btn = $('<a href="#" class="btn btn-downarrow">More</a>');
  btn.bind('click',function(){
    $('.more-options').hide();
    
    var i = $(this);
    i.parent().find('.more-options').fadeIn(300);
    return false;
  });
  
  var mo = $('<span class="more-options">' + 
    '<a href="#">Edit</a>' + 
    '<a href="#">Clear Contents</a>' + 
  '</span>');
  
  mo.hover(function(){
      mouse_is_inside=true;
  }, function(){
      mouse_is_inside=false;
  });

  i.append(btn);
  i.append(mo);

  $(document).click(function(){
    if(!mouse_is_inside) {
      $('.more-options').fadeOut(300);
    }
  });  
};

$.fn.showFilter = function() {
  var mouse_is_inside = false;
  
  this.click(function(){
    var curr_el = $(this);
    var wrapper = curr_el.parent().parent();
    var link = curr_el.parent();
    
    if(wrapper.hasClass('active')){
      wrapper.removeClass('active');
    }else{
      $('.filter-wrapper.active').removeClass('active');
      wrapper.addClass('active');
    }
    
    $(wrapper,link).hover(function(){
        mouse_is_inside=true;
    }, function(){
        mouse_is_inside=false;
    });
    
    return false;
  });
  
  $(document).click(function(){
    if(!mouse_is_inside) {
      $('.filter-wrapper.active').removeClass('active');
    }
  });  
};

$.fn.disabler = function () {
    this.each(function (eid, el) {

        // Function that resizes the overlay
        var resizeIt = function (_disabler, el) {
            var _height = el.height();
            _height += parseInt(el.css("padding-top"), 10) + parseInt(el.css("padding-bottom"), 10);
            _height += parseInt(el.css("margin-top"), 10) + parseInt(el.css("margin-bottom"), 10);
            _height += parseInt(el.css("borderTopWidth"), 10) + parseInt(el.css("borderBottomWidth"), 10);

            var _width = el.width();
            _width += parseInt(el.css("padding-left"), 10) + parseInt(el.css("padding-right"), 10);
            _width += parseInt(el.css("margin-left"), 10) + parseInt(el.css("margin-right"), 10);
            _width += parseInt(el.css("borderLeftWidth"), 10) + parseInt(el.css("borderRightWidth"), 10);

            _disabler.css({
                'width': _width - 2 + 'px',
                'height': _height + 'px'
            });
        }

        // wrapping element
        el = $(el);

        // Overlay obj
        var _disabler = $('<span class="disabler"></span>');

        el.css({
            'position': 'relative'
        });

        // Style the overlay
        _disabler.css({
            'display': 'none',
            'position': 'absolute',
            'top': '0px',
            'left': '0px',
            'background': '#fff',
            'opacity': .7,
            'z-index': 9999
        });
        // Resize the overlay
        resizeIt(_disabler, el);
        // Add the overlay to the wrapping element
        el.append(_disabler);
        // Fade in the overlay
        _disabler.fadeIn(400);

        // Resize the overlay on windows resize
        $(window).resize(function () { resizeIt(_disabler, el) });
    });
};

// Waiting...
$.fn.waiting = function () {
    this.each(function (eid, el) {

        // Function that resizes the overlay
        var resizeIt = function (_waiting, el) {
            var _height = el.height();
            _height += parseInt(el.css("padding-top"), 10) + parseInt(el.css("padding-bottom"), 10);
            _height += parseInt(el.css("margin-top"), 10) + parseInt(el.css("margin-bottom"), 10);
            _height += parseInt(el.css("borderTopWidth"), 10) + parseInt(el.css("borderBottomWidth"), 10);

            var _width = el.width();
            _width += parseInt(el.css("padding-left"), 10) + parseInt(el.css("padding-right"), 10);
            _width += parseInt(el.css("margin-left"), 10) + parseInt(el.css("margin-right"), 10);
            _width += parseInt(el.css("borderLeftWidth"), 10) + parseInt(el.css("borderRightWidth"), 10);

            _waiting.css({
                'width': _width - 2 + 'px',
                'height': _height + 'px'
            });
        }

        // wrapping element
        el = $(el);

        // Overlay obj
        var _waiting = $('<span class="waiting"></span>');

        el.css({
            'position': 'relative'
        });

        // Style the overlay
        _waiting.css({
            'display': 'none',
            'position': 'absolute',
            'top': '0px',
            'left': '0px',
            'background': '#11619D',
            'opacity': .4,
            'z-index': 99
        });
        // Resize the overlay
        resizeIt(_waiting, el);
        // Add the overlay to the wrapping element
        el.append(_waiting);
        // Fade in the overlay
        _waiting.fadeIn(400);

        // Resize the overlay on windows resize
        $(window).resize(function () { resizeIt(_waiting, el) });
    });
};

$(window).resize(function () {
    //normalize_cols_height($('.table-leads'));
    content_max_height($('.dashboard'));
    content_max_height($('.leads-view'));
});

// Set content height max possible height
function content_max_height(page) {
    if (page.length > 0) {
        var header_height = $('#header').height() + 23;
        var vp_height = $(window).height();
        var doc_height = $(document).height();
        var pan_height = (vp_height - header_height) - 26;
        if (doc_height < vp_height)
            $('.content').height(pan_height);
    }
}

// Normalize cols height
function normalize_cols_height(table) {
    var title_h = table.find('.title').height();
    table.find('.title div').each(function (idx, el) {
        //console.log($(el).padding());
        $(el).find('.w').css('height', title_h - 20);
    });

    table.find('.line').each(function (idx_line, el_line) {
        var line_h = $(el_line).height() - 20;
        $(el_line).find('div').each(function (idx_col, el_col) {
            $(el_col).find('.w').css('min-height', line_h);
        });
    });
}

// Fancybox set up
function init_fancybox() {
    if ($('#popup-deleteusers').length > 0) {
        $.fancybox($('#popup-deleteusers'), {
            padding: 0,
            closeBtn: false,
            helpers: {
                overlay: {
                    opacity: 0.8,
                    css: {
                        'background-color': '#11619d'
                    }
                }
            },
            beforeClose: function () {
                return false;
            }
        });
    }

    if ($('#popup-processing').length > 0) {
        $.fancybox($('#popup-processing'), {
            padding: 0,
            closeBtn: false,
            helpers: {
                overlay: {
                    opacity: 0.8,
                    css: {
                        'background-color': '#11619d'
                    }
                }
            },
            beforeClose: function () {
                return false;
            }
        });
    }

    if ($('#popup-onlyoneuser').length > 0) {
        $.fancybox($('#popup-onlyoneuser'), {
            padding: 0,
            closeBtn: false,
            helpers: {
                overlay: {
                    opacity: 0.8,
                    css: {
                        'background-color': '#11619d'
                    }
                }
            },
            beforeClose: function () {
                return false;
            }
        });
    }
}

// init select line
function initSelectLine() {
    var selectedClass = 'selected-line';
    $('.table').each(function () {
        var holder = $(this),
			lines = holder.find('.line');
        lines.each(function () {
            var line = $(this),
				chBox = line.find('input:checkbox');
            if (chBox.get(0) != undefined && chBox.get(0).checked) {
                line.addClass(selectedClass);
            } else {
                line.removeClass(selectedClass);
            }
            chBox.bind('change', function () {
                if (chBox.get(0) != undefined && chBox.get(0).checked) {
                    line.addClass(selectedClass);
                } else {
                    line.removeClass(selectedClass);
                }
            });
        });
    });
}

// initNavIndexes()
function initNavIndexes() {
    var nav = document.getElementById("steps");
    if (nav) {
        var lis = nav.getElementsByTagName("li");
        for (var i = 0; i < lis.length; i++) {
            //lis[i].style.zIndex = i+1;
            lis[i].style.zIndex = lis.length - i;
        }
    }
}

// clear inputs on focus
function initInputs() {
    // replace options
    var opt = {
        clearInputs: true,
        clearTextareas: true,
        clearPasswords: true
    }
    // collect all items
    var inputs = [].concat(
		PlaceholderInput.convertToArray(document.getElementsByTagName('input')),
		PlaceholderInput.convertToArray(document.getElementsByTagName('textarea'))
	);
    // apply placeholder class on inputs
    for (var i = 0; i < inputs.length; i++) {
        if (inputs[i].className.indexOf('default') < 0) {
            var inputType = PlaceholderInput.getInputType(inputs[i]);
            if ((opt.clearInputs && inputType === 'text') ||
				(opt.clearTextareas && inputType === 'textarea') ||
				(opt.clearPasswords && inputType === 'password')) {
                new PlaceholderInput({
                    element: inputs[i],
                    wrapWithElement: false,
                    showUntilTyping: false,
                    getParentByClass: false,
                    placeholderAttr: 'value'
                });
            }
        }
    }
}

// input type placeholder class
; (function () {
    PlaceholderInput = function () {
        this.options = {
            element: null,
            showUntilTyping: false,
            wrapWithElement: false,
            getParentByClass: false,
            placeholderAttr: 'value',
            inputFocusClass: 'focus',
            inputActiveClass: 'text-active',
            parentFocusClass: 'parent-focus',
            parentActiveClass: 'parent-active',
            labelFocusClass: 'label-focus',
            labelActiveClass: 'label-active',
            fakeElementClass: 'input-placeholder-text'
        }
        this.init.apply(this, arguments);
    }
    PlaceholderInput.convertToArray = function (collection) {
        var arr = [];
        for (var i = 0, ref = arr.length = collection.length; i < ref; i++) {
            arr[i] = collection[i];
        }
        return arr;
    }
    PlaceholderInput.getInputType = function (input) {
        return (input.type ? input.type : input.tagName).toLowerCase();
    }
    PlaceholderInput.prototype = {
        init: function (opt) {
            this.setOptions(opt);
            if (this.element && this.element.PlaceholderInst) {
                this.element.PlaceholderInst.refreshClasses();
            } else {
                this.element.PlaceholderInst = this;
                if (this.elementType == 'text' || this.elementType == 'password' || this.elementType == 'textarea') {
                    this.initElements();
                    this.attachEvents();
                    this.refreshClasses();
                }
            }
        },
        setOptions: function (opt) {
            for (var p in opt) {
                if (opt.hasOwnProperty(p)) {
                    this.options[p] = opt[p];
                }
            }
            if (this.options.element) {
                this.element = this.options.element;
                this.elementType = PlaceholderInput.getInputType(this.element);
                this.wrapWithElement = (this.elementType === 'password' || this.options.showUntilTyping ? true : this.options.wrapWithElement);
                this.setOrigValue(this.options.placeholderAttr == 'value' ? this.element.defaultValue : this.element.getAttribute(this.options.placeholderAttr));
            }
        },
        setOrigValue: function (value) {
            this.origValue = value;
        },
        initElements: function () {
            // create fake element if needed
            if (this.wrapWithElement) {
                //this.element.value = '';
                this.element.removeAttribute(this.options.placeholderAttr);
                this.fakeElement = document.createElement('span');
                this.fakeElement.className = this.options.fakeElementClass;
                this.fakeElement.innerHTML += this.origValue;
                this.fakeElement.style.color = getStyle(this.element, 'color');
                this.fakeElement.style.position = 'absolute';
                this.element.parentNode.insertBefore(this.fakeElement, this.element);
            }
            // get input label
            if (this.element.id) {
                this.labels = document.getElementsByTagName('label');
                for (var i = 0; i < this.labels.length; i++) {
                    if (this.labels[i].htmlFor === this.element.id) {
                        this.labelFor = this.labels[i];
                        break;
                    }
                }
            }
            // get parent node (or parentNode by className)
            this.elementParent = this.element.parentNode;
            if (typeof this.options.getParentByClass === 'string') {
                var el = this.element;
                while (el.parentNode) {
                    if (hasClass(el.parentNode, this.options.getParentByClass)) {
                        this.elementParent = el.parentNode;
                        break;
                    } else {
                        el = el.parentNode;
                    }
                }
            }
        },
        attachEvents: function () {
            this.element.onfocus = bindScope(this.focusHandler, this);
            this.element.onblur = bindScope(this.blurHandler, this);
            if (this.options.showUntilTyping) {
                this.element.onkeydown = bindScope(this.typingHandler, this);
                this.element.onpaste = bindScope(this.typingHandler, this);
            }
            if (this.wrapWithElement) this.fakeElement.onclick = bindScope(this.focusSetter, this);
        },
        togglePlaceholderText: function (state) {
            if (this.wrapWithElement) {
                this.fakeElement.style.display = state ? '' : 'none';
            } else {
                //this.element.value = state ? this.origValue : '';
                //this.element.value = this.origValue;  state ? this.origValue : '';
            }
        },
        focusSetter: function () {
            this.element.focus();
        },
        focusHandler: function () {
            this.focused = true;
            if (!this.element.value.length || this.element.value === this.origValue) {
                if (!this.options.showUntilTyping) {
                    this.togglePlaceholderText(false);
                }
            }
            this.refreshClasses();
        },
        blurHandler: function () {
            this.focused = false;
            if (!this.element.value.length || this.element.value === this.origValue) {
                this.togglePlaceholderText(true);
            }
            this.refreshClasses();
        },
        typingHandler: function () {
            setTimeout(bindScope(function () {
                if (this.element.value.length) {
                    this.togglePlaceholderText(false);
                    this.refreshClasses();
                }
            }, this), 10);
        },
        refreshClasses: function () {
            this.textActive = this.focused || (this.element.value.length && this.element.value !== this.origValue);
            this.setStateClass(this.element, this.options.inputFocusClass, this.focused);
            this.setStateClass(this.elementParent, this.options.parentFocusClass, this.focused);
            this.setStateClass(this.labelFor, this.options.labelFocusClass, this.focused);
            this.setStateClass(this.element, this.options.inputActiveClass, this.textActive);
            this.setStateClass(this.elementParent, this.options.parentActiveClass, this.textActive);
            this.setStateClass(this.labelFor, this.options.labelActiveClass, this.textActive);
        },
        setStateClass: function (el, cls, state) {
            if (!el) 
                return; 
            else if (state) 
                addClass(el, cls); 
            else 
                removeClass(el, cls);
        }
    }

    // utility functions
    function hasClass(el, cls) {
        return el.className ? el.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')) : false;
    }
    function addClass(el, cls) {
        if (!hasClass(el, cls)) el.className += " " + cls;
    }
    function removeClass(el, cls) {
        if (hasClass(el, cls)) { el.className = el.className.replace(new RegExp('(\\s|^)' + cls + '(\\s|$)'), ' '); }
    }
    function bindScope(f, scope) {
        return function () { return f.apply(scope, arguments) }
    }
    function getStyle(el, prop) {
        if (document.defaultView && document.defaultView.getComputedStyle) {
            return document.defaultView.getComputedStyle(el, null)[prop];
        } else if (el.currentStyle) {
            return el.currentStyle[prop];
        } else {
            return el.style[prop];
        }
    }
} ());

/*
* JavaScript Custom Forms 1.4.1
*/
jcf = {
    // global options
    modules: {},
    plugins: {},
    baseOptions: {
        useNativeDropOnMobileDevices: true,
        unselectableClass: 'jcf-unselectable',
        labelActiveClass: 'jcf-label-active',
        labelDisabledClass: 'jcf-label-disabled',
        classPrefix: 'jcf-class-',
        hiddenClass: 'jcf-hidden',
        focusClass: 'jcf-focus',
        wrapperTag: 'div'
    },
    // replacer function
    customForms: {
        setOptions: function (obj) {
            for (var p in obj) {
                if (obj.hasOwnProperty(p) && typeof obj[p] === 'object') {
                    jcf.lib.extend(jcf.modules[p].prototype.defaultOptions, obj[p]);
                }
            }
        },
        replaceAll: function () {
            for (var k in jcf.modules) {
                var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector);
                for (var i = 0; i < els.length; i++) {
                    if (els[i].jcf) {
                        // refresh form element state
                        els[i].jcf.refreshState();
                    } else {
                        // replace form element
                        if (!jcf.lib.hasClass(els[i], 'default') && jcf.modules[k].prototype.checkElement(els[i])) {
                            new jcf.modules[k]({
                                replaces: els[i]
                            });
                        }
                    }
                }
            }
        },
        replaceElement: function (elsId) {
            var k = 'select';
           
           var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector);
            for (var i = 0; i < els.length; i++) {
                /*
                if (els[i].jcf) {
                    // refresh form element state
                    els[i].jcf.refreshState();
                } else {
                    // replace form element
                    if (!jcf.lib.hasClass(els[i], 'default') && jcf.modules[k].prototype.checkElement(els[i])) {
                        new jcf.modules[k]({
                            replaces: els[i]
                        });
                    }
                }
                */
                // replace form element
                if(els[i].id == elsId)
                {
                    if (!jcf.lib.hasClass(els[i], 'default') && jcf.modules[k].prototype.checkElement(els[i])) {
                        new jcf.modules[k]({
                            replaces: els[i]
                        });
                    }

                    break;
                }
            }
        },
        refreshAll: function () {
            for (var k in jcf.modules) {
                var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector);
                for (var i = 0; i < els.length; i++) {
                    if (els[i].jcf) {
                        // refresh form element state
                        els[i].jcf.refreshState();
                    }
                }
            }
        },
        refreshElement: function (obj) {
            if (obj && obj.jcf) {
                obj.jcf.refreshState();
            }
        },
        destroyAll: function () {
            for (var k in jcf.modules) {
                var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector);
                for (var i = 0; i < els.length; i++) {
                    if (els[i].jcf) {
                        els[i].jcf.destroy();
                    }
                }
            }
        }
    },
    // detect device type
    isTouchDevice: (function () {
        try {
            return ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;
        } catch (e) {
            return false;
        }
    } ()),
    // define base module
    setBaseModule: function (obj) {
        jcf.customControl = function (opt) {
            this.options = jcf.lib.extend({}, jcf.baseOptions, this.defaultOptions, opt);
            this.init();
        }
        for (var p in obj) {
            jcf.customControl.prototype[p] = obj[p];
        }
    },
    // add module to jcf.modules
    addModule: function (obj) {
        if (obj.name) {
            // create new module proto class
            jcf.modules[obj.name] = function () {
                jcf.modules[obj.name].superclass.constructor.apply(this, arguments);
            }
            jcf.lib.inherit(jcf.modules[obj.name], jcf.customControl);
            for (var p in obj) {
                jcf.modules[obj.name].prototype[p] = obj[p]
            }
            // on create module
            jcf.modules[obj.name].prototype.onCreateModule();
            // make callback for exciting modules
            for (var mod in jcf.modules) {
                if (jcf.modules[mod] != jcf.modules[obj.name]) {
                    jcf.modules[mod].prototype.onModuleAdded(jcf.modules[obj.name]);
                }
            }
        }
    },
    // add plugin to jcf.plugins
    addPlugin: function (obj) {
        if (obj && obj.name) {
            jcf.plugins[obj.name] = function () {
                this.init.apply(this, arguments);
            }
            for (var p in obj) {
                jcf.plugins[obj.name].prototype[p] = obj[p];
            }
        }
    },
    // miscellaneous init
    init: function () {
        this.eventPress = this.isTouchDevice ? 'touchstart' : 'mousedown';
        this.eventMove = this.isTouchDevice ? 'touchmove' : 'mousemove';
        this.eventRelease = this.isTouchDevice ? 'touchend' : 'mouseup';
        return this;
    },
    initStyles: function () {
        // create <style> element and rules
        var head = document.getElementsByTagName('head')[0],
			style = document.createElement('style'),
			rules = document.createTextNode('.' + jcf.baseOptions.unselectableClass + '{' +
				'-moz-user-select:none;' +
				'-webkit-tap-highlight-color:rgba(255,255,255,0);' +
				'-webkit-user-select:none;' +
				'user-select:none;' +
			'}');

        // append style element
        style.type = 'text/css';
        if (style.styleSheet) {
            style.styleSheet.cssText = rules.nodeValue;
        } else {
            style.appendChild(rules);
        }
        head.appendChild(style);
    }
}.init();

/*
* Custom Form Control prototype
*/
jcf.setBaseModule({
    init: function () {
        if (this.options.replaces) {
            this.realElement = this.options.replaces;
            this.realElement.jcf = this;
            this.replaceObject();
        }
    },
    defaultOptions: {
        // default module options (will be merged with base options)
    },
    checkElement: function (el) {
        return true; // additional check for correct form element
    },
    replaceObject: function () {
        this.createWrapper();
        this.attachEvents();
        this.fixStyles();
        this.setupWrapper();
    },
    createWrapper: function () {
        this.fakeElement = jcf.lib.createElement(this.options.wrapperTag);
        this.labelFor = jcf.lib.getLabelFor(this.realElement);
        jcf.lib.disableTextSelection(this.fakeElement);
        jcf.lib.addClass(this.fakeElement, jcf.lib.getAllClasses(this.realElement.className, this.options.classPrefix));
        jcf.lib.addClass(this.realElement, jcf.baseOptions.hiddenClass);
    },
    attachEvents: function () {
        jcf.lib.event.add(this.realElement, 'focus', this.onFocusHandler, this);
        jcf.lib.event.add(this.realElement, 'blur', this.onBlurHandler, this);
        jcf.lib.event.add(this.fakeElement, 'click', this.onFakeClick, this);
        jcf.lib.event.add(this.fakeElement, jcf.eventPress, this.onFakePressed, this);
        jcf.lib.event.add(this.fakeElement, jcf.eventRelease, this.onFakeReleased, this);

        if (this.labelFor) {
            this.labelFor.jcf = this;
            jcf.lib.event.add(this.labelFor, 'click', this.onFakeClick, this);
            jcf.lib.event.add(this.labelFor, jcf.eventPress, this.onFakePressed, this);
            jcf.lib.event.add(this.labelFor, jcf.eventRelease, this.onFakeReleased, this);
        }
    },
    fixStyles: function () {
        // hide mobile webkit tap effect
        if (jcf.isTouchDevice) {
            var tapStyle = 'rgba(255,255,255,0)';
            this.realElement.style.webkitTapHighlightColor = tapStyle;
            this.fakeElement.style.webkitTapHighlightColor = tapStyle;
            if (this.labelFor) {
                this.labelFor.style.webkitTapHighlightColor = tapStyle;
            }
        }
    },
    setupWrapper: function () {
        // implement in subclass
    },
    refreshState: function () {
        // implement in subclass
    },
    destroy: function () {
        if (this.fakeElement && this.fakeElement.parentNode) {
            this.fakeElement.parentNode.removeChild(this.fakeElement);
        }
        jcf.lib.removeClass(this.realElement, jcf.baseOptions.hiddenClass);
        this.realElement.jcf = null;
    },
    onFocus: function () {
        // emulated focus event
        jcf.lib.addClass(this.fakeElement, this.options.focusClass);
    },
    onBlur: function (cb) {
        // emulated blur event
        jcf.lib.removeClass(this.fakeElement, this.options.focusClass);
    },
    onFocusHandler: function () {
        // handle focus loses
        if (this.focused) return;
        this.focused = true;

        // handle touch devices also
        if (jcf.isTouchDevice) {
            if (jcf.focusedInstance && jcf.focusedInstance.realElement != this.realElement) {
                jcf.focusedInstance.onBlur();
                jcf.focusedInstance.realElement.blur();
            }
            jcf.focusedInstance = this;
        }
        this.onFocus.apply(this, arguments);
    },
    onBlurHandler: function () {
        // handle focus loses
        if (!this.pressedFlag) {
            this.focused = false;
            this.onBlur.apply(this, arguments);
        }
    },
    onFakeClick: function () {
        if (jcf.isTouchDevice) {
            this.onFocus();
        } else if (!this.realElement.disabled) {
            this.realElement.focus();
        }
    },
    onFakePressed: function (e) {
        this.pressedFlag = true;
    },
    onFakeReleased: function () {
        this.pressedFlag = false;
    },
    onCreateModule: function () {
        // implement in subclass
    },
    onModuleAdded: function (module) {
        // implement in subclass
    },
    onControlReady: function () {
        // implement in subclass
    }
});

/*
* JCF Utility Library
*/
jcf.lib = {
    bind: function (func, scope) {
        return function () {
            return func.apply(scope, arguments);
        }
    },
    browser: (function () {
        var ua = navigator.userAgent.toLowerCase(), res = {},
		match = /(webkit)[ \/]([\w.]+)/.exec(ua) || /(opera)(?:.*version)?[ \/]([\w.]+)/.exec(ua) ||
				/(msie) ([\w.]+)/.exec(ua) || ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+))?/.exec(ua) || [];
        res[match[1]] = true;
        res.version = match[2] || "0";
        res.safariMac = ua.indexOf('mac') != -1 && ua.indexOf('safari') != -1;
        return res;
    })(),
    getOffset: function (obj) {
        if (obj.getBoundingClientRect) {
            var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft;
            var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
            var clientLeft = document.documentElement.clientLeft || document.body.clientLeft || 0;
            var clientTop = document.documentElement.clientTop || document.body.clientTop || 0;
            return {
                top: Math.round(obj.getBoundingClientRect().top + scrollTop - clientTop),
                left: Math.round(obj.getBoundingClientRect().left + scrollLeft - clientLeft)
            }
        } else {
            var posLeft = 0, posTop = 0;
            while (obj.offsetParent) { posLeft += obj.offsetLeft; posTop += obj.offsetTop; obj = obj.offsetParent; }
            return { top: posTop, left: posLeft };
        }
    },
    getScrollTop: function () {
        return window.pageYOffset || document.documentElement.scrollTop;
    },
    getScrollLeft: function () {
        return window.pageXOffset || document.documentElement.scrollLeft;
    },
    getWindowWidth: function () {
        return document.compatMode == 'CSS1Compat' ? document.documentElement.clientWidth : document.body.clientWidth;
    },
    getWindowHeight: function () {
        return document.compatMode == 'CSS1Compat' ? document.documentElement.clientHeight : document.body.clientHeight;
    },
    getStyle: function (el, prop) {
        if (document.defaultView && document.defaultView.getComputedStyle) {
            return document.defaultView.getComputedStyle(el, null)[prop];
        } else if (el.currentStyle) {
            return el.currentStyle[prop];
        } else {
            return el.style[prop];
        }
    },
    getParent: function (obj, selector) {
        while (obj.parentNode && obj.parentNode != document.body) {
            if (obj.parentNode.tagName.toLowerCase() == selector.toLowerCase()) {
                return obj.parentNode;
            }
            obj = obj.parentNode;
        }
        return false;
    },
    isParent: function (child, parent) {
        while (child.parentNode) {
            if (child.parentNode === parent) {
                return true;
            }
            child = child.parentNode;
        }
        return false;
    },
    getLabelFor: function (object) {
        if (jcf.lib.getParent(object, 'label')) {
            return object.parentNode;
        } else if (object.id) {
            return jcf.lib.queryBySelector('label[for="' + object.id + '"]')[0];
        }
    },
    disableTextSelection: function (el) {
        if (typeof el.onselectstart !== 'undefined') {
            el.onselectstart = function () { return false };
        } else if (window.opera) {
            el.setAttribute('unselectable', 'on');
        } else {
            jcf.lib.addClass(el, jcf.baseOptions.unselectableClass);
        }
    },
    enableTextSelection: function (el) {
        if (typeof el.onselectstart !== 'undefined') {
            el.onselectstart = null;
        } else if (window.opera) {
            el.removeAttribute('unselectable');
        } else {
            jcf.lib.removeClass(el, jcf.baseOptions.unselectableClass);
        }
    },
    queryBySelector: function (selector, scope) {
        return this.getElementsBySelector(selector, scope);
    },
    prevSibling: function (node) {
        while (node = node.previousSibling) if (node.nodeType == 1) break;
        return node;
    },
    nextSibling: function (node) {
        while (node = node.nextSibling) if (node.nodeType == 1) break;
        return node;
    },
    fireEvent: function (element, event) {
        if (document.createEventObject) {
            var evt = document.createEventObject();
            return element.fireEvent('on' + event, evt)
        }
        else {
            var evt = document.createEvent('HTMLEvents');
            evt.initEvent(event, true, true);
            return !element.dispatchEvent(evt);
        }
    },
    isParent: function (p, c) {
        while (c.parentNode) {
            if (p == c) {
                return true;
            }
            c = c.parentNode;
        }
        return false;
    },
    inherit: function (Child, Parent) {
        var F = function () { }
        F.prototype = Parent.prototype
        Child.prototype = new F()
        Child.prototype.constructor = Child
        Child.superclass = Parent.prototype
    },
    extend: function (obj) {
        for (var i = 1; i < arguments.length; i++) {
            for (var p in arguments[i]) {
                if (arguments[i].hasOwnProperty(p)) {
                    obj[p] = arguments[i][p];
                }
            }
        }
        return obj;
    },
    hasClass: function (obj, cname) {
        return obj != undefined && obj != null && (obj.className ? obj.className.match(new RegExp('(\\s|^)' + cname + '(\\s|$)')) : false);
    },
    addClass: function (obj, cname) {
        if (obj != undefined && obj != null && !this.hasClass(obj, cname)) obj.className += (!obj.className.length || obj.className.charAt(obj.className.length - 1) === ' ' ? '' : ' ') + cname;
    },
    removeClass: function (obj, cname) {
        if (obj != undefined && obj != null && this.hasClass(obj, cname)) obj.className = obj.className.replace(new RegExp('(\\s|^)' + cname + '(\\s|$)'), ' ').replace(/\s+$/, '');
    },
    toggleClass: function (obj, cname, condition) {
        if (condition) this.addClass(obj, cname); else this.removeClass(obj, cname);
    },
    createElement: function (tagName, options) {
        var el = document.createElement(tagName);
        for (var p in options) {
            if (options.hasOwnProperty(p)) {
                switch (p) {
                    case 'class': el.className = options[p]; break;
                    case 'html': el.innerHTML = options[p]; break;
                    case 'style': this.setStyles(el, options[p]); break;
                    default: el.setAttribute(p, options[p]);
                }
            }
        }
        return el;
    },
    setStyles: function (el, styles) {
        for (var p in styles) {
            if (styles.hasOwnProperty(p)) {
                switch (p) {
                    case 'float': el.style.cssFloat = styles[p]; break;
                    case 'opacity': el.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + styles[p] * 100 + ')'; el.style.opacity = styles[p]; break;
                    default: el.style[p] = (typeof styles[p] === 'undefined' ? 0 : styles[p]) + (typeof styles[p] === 'number' ? 'px' : '');
                }
            }
        }
        return el;
    },
    getInnerWidth: function (el) {
        return el.offsetWidth - (parseInt(this.getStyle(el, 'paddingLeft')) || 0) - (parseInt(this.getStyle(el, 'paddingRight')) || 0);
    },
    getInnerHeight: function (el) {
        return el.offsetHeight - (parseInt(this.getStyle(el, 'paddingTop')) || 0) - (parseInt(this.getStyle(el, 'paddingBottom')) || 0);
    },
    getAllClasses: function (cname, prefix, skip) {
        if (!skip) skip = '';
        if (!prefix) prefix = '';
        return cname ? cname.replace(new RegExp('(\\s|^)' + skip + '(\\s|$)'), ' ').replace(/[\s]*([\S]+)+[\s]*/gi, prefix + "$1 ") : '';
    },
    getElementsBySelector: function (selector, scope) {
        if (typeof document.querySelectorAll === 'function') {
            return (scope || document).querySelectorAll(selector);
        }
        var selectors = selector.split(',');
        var resultList = [];
        for (var s = 0; s < selectors.length; s++) {
            var currentContext = [scope || document];
            var tokens = selectors[s].replace(/^\s+/, '').replace(/\s+$/, '').split(' ');
            for (var i = 0; i < tokens.length; i++) {
                token = tokens[i].replace(/^\s+/, '').replace(/\s+$/, '');
                if (token.indexOf('#') > -1) {
                    var bits = token.split('#'), tagName = bits[0], id = bits[1];
                    var element = document.getElementById(id);
                    if (tagName && element.nodeName.toLowerCase() != tagName) {
                        return [];
                    }
                    currentContext = [element];
                    continue;
                }
                if (token.indexOf('.') > -1) {
                    var bits = token.split('.'), tagName = bits[0] || '*', className = bits[1], found = [], foundCount = 0;
                    for (var h = 0; h < currentContext.length; h++) {
                        var elements;
                        if (tagName == '*') {
                            elements = currentContext[h].getElementsByTagName('*');
                        } else {
                            elements = currentContext[h].getElementsByTagName(tagName);
                        }
                        for (var j = 0; j < elements.length; j++) {
                            found[foundCount++] = elements[j];
                        }
                    }
                    currentContext = [];
                    var currentContextIndex = 0;
                    for (var k = 0; k < found.length; k++) {
                        if (found[k].className && found[k].className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'))) {
                            currentContext[currentContextIndex++] = found[k];
                        }
                    }
                    continue;
                }
                if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
                    var tagName = RegExp.$1 || '*', attrName = RegExp.$2, attrOperator = RegExp.$3, attrValue = RegExp.$4;
                    if (attrName.toLowerCase() == 'for' && this.browser.msie && this.browser.version < 8) {
                        attrName = 'htmlFor';
                    }
                    var found = [], foundCount = 0;
                    for (var h = 0; h < currentContext.length; h++) {
                        var elements;
                        if (tagName == '*') {
                            elements = currentContext[h].getElementsByTagName('*');
                        } else {
                            elements = currentContext[h].getElementsByTagName(tagName);
                        }
                        for (var j = 0; elements[j]; j++) {
                            found[foundCount++] = elements[j];
                        }
                    }
                    currentContext = [];
                    var currentContextIndex = 0, checkFunction;
                    switch (attrOperator) {
                        case '=': checkFunction = function (e) { return (e.getAttribute(attrName) == attrValue) }; break;
                        case '~': checkFunction = function (e) { return (e.getAttribute(attrName).match(new RegExp('(\\s|^)' + attrValue + '(\\s|$)'))) }; break;
                        case '|': checkFunction = function (e) { return (e.getAttribute(attrName).match(new RegExp('^' + attrValue + '-?'))) }; break;
                        case '^': checkFunction = function (e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0) }; break;
                        case '$': checkFunction = function (e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length) }; break;
                        case '*': checkFunction = function (e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1) }; break;
                        default: checkFunction = function (e) { return e.getAttribute(attrName) };
                    }
                    currentContext = [];
                    var currentContextIndex = 0;
                    for (var k = 0; k < found.length; k++) {
                        if (checkFunction(found[k])) {
                            currentContext[currentContextIndex++] = found[k];
                        }
                    }
                    continue;
                }
                tagName = token;
                var found = [], foundCount = 0;
                for (var h = 0; h < currentContext.length; h++) {
                    var elements = currentContext[h].getElementsByTagName(tagName);
                    for (var j = 0; j < elements.length; j++) {
                        found[foundCount++] = elements[j];
                    }
                }
                currentContext = found;
            }
            resultList = [].concat(resultList, currentContext);
        }
        return resultList;
    },
    scrollSize: (function () {
        var content, hold, sizeBefore, sizeAfter;
        function buildSizer() {
            if (hold) removeSizer();
            content = document.createElement('div');
            hold = document.createElement('div');
            hold.style.cssText = 'position:absolute;overflow:hidden;width:100px;height:100px';
            hold.appendChild(content);
            document.body.appendChild(hold);
        }
        function removeSizer() {
            document.body.removeChild(hold);
            hold = null;
        }
        function calcSize(vertical) {
            buildSizer();
            content.style.cssText = 'height:' + (vertical ? '100%' : '200px');
            sizeBefore = (vertical ? content.offsetHeight : content.offsetWidth);
            hold.style.overflow = 'scroll'; content.innerHTML = 1;
            sizeAfter = (vertical ? content.offsetHeight : content.offsetWidth);
            if (vertical && hold.clientHeight) sizeAfter = hold.clientHeight;
            removeSizer();
            return sizeBefore - sizeAfter;
        }
        return {
            getWidth: function () {
                return calcSize(false);
            },
            getHeight: function () {
                return calcSize(true)
            }
        }
    } ()),
    domReady: function (handler) {
        var called = false
        function ready() {
            if (called) return;
            called = true;
            handler();
        }
        if (document.addEventListener) {
            document.addEventListener("DOMContentLoaded", ready, false);
        } else if (document.attachEvent) {
            if (document.documentElement.doScroll && window == window.top) {
                function tryScroll() {
                    if (called) return
                    if (!document.body) return
                    try {
                        document.documentElement.doScroll("left")
                        ready()
                    } catch (e) {
                        setTimeout(tryScroll, 0)
                    }
                }
                tryScroll()
            }
            document.attachEvent("onreadystatechange", function () {
                if (document.readyState === "complete") {
                    ready()
                }
            })
        }
        if (window.addEventListener) window.addEventListener('load', ready, false)
        else if (window.attachEvent) window.attachEvent('onload', ready)
    },
    event: (function () {
        var guid = 0;
        function fixEvent(e) {
            e = e || window.event;
            if (e.isFixed) {
                return e;
            }
            e.isFixed = true;
            e.preventDefault = e.preventDefault || function () { this.returnValue = false }
            e.stopPropagation = e.stopPropagaton || function () { this.cancelBubble = true }
            if (!e.target) {
                e.target = e.srcElement
            }
            if (!e.relatedTarget && e.fromElement) {
                e.relatedTarget = e.fromElement == e.target ? e.toElement : e.fromElement;
            }
            if (e.pageX == null && e.clientX != null) {
                var html = document.documentElement, body = document.body;
                e.pageX = e.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0) - (html.clientLeft || 0);
                e.pageY = e.clientY + (html && html.scrollTop || body && body.scrollTop || 0) - (html.clientTop || 0);
            }
            if (!e.which && e.button) {
                e.which = e.button & 1 ? 1 : (e.button & 2 ? 3 : (e.button & 4 ? 2 : 0));
            }
            if (e.type === "DOMMouseScroll" || e.type === 'mousewheel') {
                e.mWheelDelta = 0;
                if (e.wheelDelta) {
                    e.mWheelDelta = e.wheelDelta / 120;
                } else if (e.detail) {
                    e.mWheelDelta = -e.detail / 3;
                }
            }
            return e;
        }
        function commonHandle(event, customScope) {
            event = fixEvent(event);
            var handlers = this.events[event.type];
            for (var g in handlers) {
                var handler = handlers[g];
                var ret = handler.call(customScope || this, event);
                if (ret === false) {
                    event.preventDefault()
                    event.stopPropagation()
                }
            }
        }
        var publicAPI = {
            add: function (elem, type, handler, forcedScope) {
                if (elem.setInterval && (elem != window && !elem.frameElement)) {
                    elem = window;
                }
                if (!handler.guid) {
                    handler.guid = ++guid;
                }
                if (!elem.events) {
                    elem.events = {};
                    elem.handle = function (event) {
                        return commonHandle.call(elem, event);
                    }
                }
                if (!elem.events[type]) {
                    elem.events[type] = {};
                    if (elem.addEventListener) elem.addEventListener(type, elem.handle, false);
                    else if (elem.attachEvent) elem.attachEvent("on" + type, elem.handle);
                    if (type === 'mousewheel') {
                        publicAPI.add(elem, 'DOMMouseScroll', handler, forcedScope);
                    }
                }
                var fakeHandler = jcf.lib.bind(handler, forcedScope);
                fakeHandler.guid = handler.guid;
                elem.events[type][handler.guid] = forcedScope ? fakeHandler : handler;
            },
            remove: function (elem, type, handler) {
                var handlers = elem.events && elem.events[type];
                if (!handlers) return;
                delete handlers[handler.guid];
                for (var any in handlers) return;
                if (elem.removeEventListener) elem.removeEventListener(type, elem.handle, false);
                else if (elem.detachEvent) elem.detachEvent("on" + type, elem.handle);
                delete elem.events[type];
                for (var any in elem.events) return;
                try {
                    delete elem.handle;
                    delete elem.events;
                } catch (e) {
                    if (elem.removeAttribute) {
                        elem.removeAttribute("handle");
                        elem.removeAttribute("events");
                    }
                }
                if (type === 'mousewheel') {
                    publicAPI.remove(elem, 'DOMMouseScroll', handler);
                }
            }
        }
        return publicAPI;
    } ())
}

// init jcf styles
jcf.lib.domReady(function () {
    jcf.initStyles();
});

// custom select module
jcf.addModule({
    name: 'select',
    selector: 'select',
    defaultOptions: {
        hideDropOnScroll: true,
        showNativeDrop: false,
        handleDropPosition: true,
        selectDropPosition: 'bottom', // or 'top'
        wrapperClass: 'select-area',
        focusClass: 'select-focus',
        dropActiveClass: 'select-active',
        selectedClass: 'item-selected',
        currentSelectedClass: 'current-selected',
        disabledClass: 'select-disabled',
        valueSelector: 'span.center',
        optGroupClass: 'optgroup',
        openerSelector: 'a.select-opener',
        selectStructure: '<span class="left"></span><span class="center"></span><a class="select-opener"></a>',
        classPrefix: 'select-',
        dropMaxHeight: 200,
        dropFlippedClass: 'select-options-flipped',
        dropHiddenClass: 'options-hidden',
        dropScrollableClass: 'options-overflow',
        dropClass: 'select-options',
        dropClassPrefix: 'drop-',
        dropStructure: '<div class="drop-holder"><div class="drop-list"></div></div>',
        dropSelector: 'div.drop-list'
    },
    checkElement: function (el) {
        return (!el.size && !el.multiple);
    },
    setupWrapper: function () {
        jcf.lib.addClass(this.fakeElement, this.options.wrapperClass);
        this.realElement.parentNode.insertBefore(this.fakeElement, this.realElement);
        this.fakeElement.innerHTML = this.options.selectStructure;
        this.fakeElement.style.width = (this.realElement.offsetWidth > 0 ? this.realElement.offsetWidth + 'px' : 'auto');

        // show native drop if specified in options
        if (jcf.isTouchDevice && jcf.baseOptions.useNativeDropOnMobileDevices) {
            this.options.showNativeDrop = true;
        }
        if (this.options.showNativeDrop) {
            this.fakeElement.appendChild(this.realElement);
            jcf.lib.removeClass(this.realElement, this.options.hiddenClass);
            jcf.lib.setStyles(this.realElement, {
                top: 0,
                left: 0,
                margin: 0,
                padding: 0,
                opacity: 0,
                border: 'none',
                position: 'absolute',
                width: jcf.lib.getInnerWidth(this.fakeElement) - 1,
                height: jcf.lib.getInnerHeight(this.fakeElement) - 1
            });
        }

        // create select body
        this.opener = jcf.lib.queryBySelector(this.options.openerSelector, this.fakeElement)[0];
        this.valueText = jcf.lib.queryBySelector(this.options.valueSelector, this.fakeElement)[0];
        jcf.lib.disableTextSelection(this.valueText);
        this.opener.jcf = this;

		this.valueText.style.width = $(this.fakeElement).width() - $(this.opener).width() + 'px';
//    	this.valueText.style.width = jcf.lib.getInnerWidth(this.fakeElement) - jcf.lib.getInnerWidth(this.opener) + 'px';

        if (!this.options.showNativeDrop) {
            this.createDropdown();
            this.refreshState();
            this.onControlReady(this);
            this.hideDropdown(true);
        } else {
            this.refreshState();
        }
        this.addEvents();
    },
    addEvents: function () {
        if (this.options.showNativeDrop) {
            jcf.lib.event.add(this.realElement, 'click', this.onChange, this);
        } else {
            jcf.lib.event.add(this.fakeElement, 'click', this.toggleDropdown, this);
        }
        jcf.lib.event.add(this.realElement, 'change', this.onChange, this);
    },
    onFakeClick: function () {
        // do nothing (drop toggles by toggleDropdown method)
    },
    onFocus: function () {
        jcf.modules[this.name].superclass.onFocus.apply(this, arguments);
        if (!this.options.showNativeDrop) {
            // Mac Safari Fix
            if (jcf.lib.browser.safariMac) {
                this.realElement.setAttribute('size', '2');
            }
            jcf.lib.event.add(this.realElement, 'keydown', this.onKeyDown, this);
            if (jcf.activeControl && jcf.activeControl != this) {
                jcf.activeControl.hideDropdown();
                jcf.activeControl = this;
            }
        }
    },
    onBlur: function () {
        if (!this.options.showNativeDrop) {
            // Mac Safari Fix
            if (jcf.lib.browser.safariMac) {
                this.realElement.removeAttribute('size');
            }
            if (!this.isActiveDrop() || !this.isOverDrop()) {
                jcf.modules[this.name].superclass.onBlur.apply(this);
                if (jcf.activeControl === this) jcf.activeControl = null;
                if (!jcf.isTouchDevice) {
                    this.hideDropdown();
                }
            }
            jcf.lib.event.remove(this.realElement, 'keydown', this.onKeyDown);
        } else {
            jcf.modules[this.name].superclass.onBlur.apply(this);
        }
    },
    onChange: function () {
        this.refreshState();
    },
    onKeyDown: function (e) {
        jcf.tmpFlag = true;
        setTimeout(function () { jcf.tmpFlag = false }, 100);
        var context = this;
        context.keyboardFix = true;
        setTimeout(function () {
            context.refreshState();
        }, 10);
        if (e.keyCode == 13) {
            context.toggleDropdown.apply(context);
            return false;
        }
    },
    onResizeWindow: function (e) {
        if (this.isActiveDrop()) {
            this.hideDropdown();
        }
    },
    onScrollWindow: function (e) {
        if (this.options.hideDropOnScroll) {
            this.hideDropdown();
        } else if (this.isActiveDrop()) {
            this.positionDropdown();
        }
    },
    onOptionClick: function (e) {
        var opener = e.target && e.target.tagName && e.target.tagName.toLowerCase() == 'li' ? e.target : jcf.lib.getParent(e.target, 'li');
        if (opener) {
            this.realElement.selectedIndex = parseInt(opener.getAttribute('rel'));
            if (jcf.isTouchDevice) {
                this.onFocus();
            } else {
                this.realElement.focus();
            }
            this.refreshState();
            this.hideDropdown();
            jcf.lib.fireEvent(this.realElement, 'change');
        }
        return false;
    },
    onClickOutside: function (e) {
        if (jcf.tmpFlag) {
            jcf.tmpFlag = false;
            return;
        }
        if (!jcf.lib.isParent(this.fakeElement, e.target) && !jcf.lib.isParent(this.selectDrop, e.target)) {
            this.hideDropdown();
        }
    },
    onDropHover: function (e) {
        if (!this.keyboardFix) {
            this.hoverFlag = true;
            var opener = e.target && e.target.tagName && e.target.tagName.toLowerCase() == 'li' ? e.target : jcf.lib.getParent(e.target, 'li');
            if (opener) {
                this.realElement.selectedIndex = parseInt(opener.getAttribute('rel'));
                this.refreshSelectedClass(parseInt(opener.getAttribute('rel')));
            }
        } else {
            this.keyboardFix = false;
        }
    },
    onDropLeave: function () {
        this.hoverFlag = false;
    },
    isActiveDrop: function () {
        return !jcf.lib.hasClass(this.selectDrop, this.options.dropHiddenClass);
    },
    isOverDrop: function () {
        return this.hoverFlag;
    },
    createDropdown: function () {
        // remove old dropdown if exists
        if (this.selectDrop) {
            this.selectDrop.parentNode.removeChild(this.selectDrop);
        }

        // create dropdown holder
        this.selectDrop = document.createElement('div');
        this.selectDrop.className = this.options.dropClass;
        this.selectDrop.innerHTML = this.options.dropStructure;
        jcf.lib.setStyles(this.selectDrop, { position: 'absolute' });
        this.selectList = jcf.lib.queryBySelector(this.options.dropSelector, this.selectDrop)[0];
        jcf.lib.addClass(this.selectDrop, this.options.dropHiddenClass);
        document.body.appendChild(this.selectDrop);
        this.selectDrop.jcf = this;
        jcf.lib.event.add(this.selectDrop, 'click', this.onOptionClick, this);
        jcf.lib.event.add(this.selectDrop, 'mouseover', this.onDropHover, this);
        jcf.lib.event.add(this.selectDrop, 'mouseout', this.onDropLeave, this);
        this.buildDropdown();
    },
    buildDropdown: function () {
        // build select options / optgroups
        this.buildDropdownOptions();

        // position and resize dropdown
        this.positionDropdown();

        // cut dropdown if height exceedes
        this.buildDropdownScroll();
    },
    buildDropdownOptions: function () {
        this.resStructure = '';
        this.optNum = 0;
        for (var i = 0; i < this.realElement.children.length; i++) {
            this.resStructure += this.buildElement(this.realElement.children[i]) + '\n';
        }
        this.selectList.innerHTML = this.resStructure;
    },
    buildDropdownScroll: function () {
        if (this.options.dropMaxHeight) {
            if (this.selectDrop.offsetHeight > this.options.dropMaxHeight) {
                this.selectList.style.height = this.options.dropMaxHeight + 'px';
                this.selectList.style.overflow = 'auto';
                this.selectList.style.overflowX = 'hidden';
                jcf.lib.addClass(this.selectDrop, this.options.dropScrollableClass);
            }
        }
        jcf.lib.addClass(this.selectDrop, jcf.lib.getAllClasses(this.realElement.className, this.options.dropClassPrefix, jcf.baseOptions.hiddenClass));
    },
    parseOptionTitle: function (optTitle) {
        return (typeof optTitle === 'string' && /\.(jpg|gif|png|bmp|jpeg)(.*)?$/i.test(optTitle)) ? optTitle : '';
    },
    buildElement: function (obj) {
        // build option
        var res = '', optImage;
        if (obj.tagName.toLowerCase() == 'option') {
            if (!jcf.lib.prevSibling(obj) || jcf.lib.prevSibling(obj).tagName.toLowerCase() != 'option') {
                res += '<ul>';
            }

            optImage = this.parseOptionTitle(obj.title);
            res += '<li rel="' + (this.optNum++) + '" class="' + (obj.className ? obj.className + ' ' : '') + 'jcfcalc"><a href="#">' + (optImage ? '<img src="' + optImage + '" alt="" />' : '') + '<span>' + obj.innerHTML + '</span></a></li>';
            if (!jcf.lib.nextSibling(obj) || jcf.lib.nextSibling(obj).tagName.toLowerCase() != 'option') {
                res += '</ul>';
            }
            return res;
        }
        // build option group with options
        else if (obj.tagName.toLowerCase() == 'optgroup' && obj.label) {
            res += '<div class="' + this.options.optGroupClass + '">';
            res += '<strong class="jcfcalc"><em>' + (obj.label) + '</em></strong>';
            for (var i = 0; i < obj.children.length; i++) {
                res += this.buildElement(obj.children[i]);
            }
            res += '</div>';
            return res;
        }
    },
    positionDropdown: function () {
        var ofs = jcf.lib.getOffset(this.fakeElement), selectAreaHeight = this.fakeElement.offsetHeight, selectDropHeight = this.selectDrop.offsetHeight;
        var fitInTop = ofs.top - selectDropHeight >= jcf.lib.getScrollTop() && jcf.lib.getScrollTop() + jcf.lib.getWindowHeight() < ofs.top + selectAreaHeight + selectDropHeight;


        if ((this.options.handleDropPosition && fitInTop) || this.options.selectDropPosition === 'top') {
            this.selectDrop.style.top = (ofs.top - selectDropHeight) + 'px';
            jcf.lib.addClass(this.selectDrop, this.options.dropFlippedClass);
        } else {
            this.selectDrop.style.top = (ofs.top + selectAreaHeight) + 'px';
            jcf.lib.removeClass(this.selectDrop, this.options.dropFlippedClass);
        }
        this.selectDrop.style.left = ofs.left + 'px';

    	var width = 0;
    	var children = jcf.lib.queryBySelector('li', this.selectList);
    	if (this.calculatedWidth == 0 || this.calculatedWidth == null) {
    		
    		var itemMaxWidth = 0;    		
    		for(var i = 0; i < children.length; i++) {
    			if (itemMaxWidth < children[i].offsetWidth) itemMaxWidth = children[i].offsetWidth;
    		}
    	    if (this.options.dropMaxHeight) {
    			if (this.selectDrop.offsetHeight > this.options.dropMaxHeight) {
    				var wide_scroll_html = '<div id="wide_scroll_div_one" style="width:50px;height:50px;overflow-y:scroll;position:absolute;top:-200px;left:-200px;"><div id="wide_scroll_div_two" style="height:100px;width:100%"></div></div>'; 
					$("body").append(wide_scroll_html); // Append our div and add the hmtl to your document for calculations
					var scroll_w1 = $("#wide_scroll_div_one").width(); // Getting the width of the surrounding(parent) div - we already know it is 50px since we styled it but just to make sure.
					var scroll_w2 = $("#wide_scroll_div_two").innerWidth(); // Find the inner width of the inner(child) div.
					var scroll_bar_width = scroll_w1 - scroll_w2; // subtract the difference
					$("#wide_scroll_div_one").remove(); // remove the html from your document    				
    				itemMaxWidth = itemMaxWidth + scroll_bar_width;
    			}
    		}
    		if (this.fakeElement.offsetWidth == 0) width = itemMaxWidth;
    		else if (itemMaxWidth <= this.fakeElement.offsetWidth) width = this.fakeElement.offsetWidth;
    		else if (itemMaxWidth <= this.fakeElement.offsetWidth * 2) width = itemMaxWidth;
    		else width = this.fakeElement.offsetWidth * 2;
    		
    		this.calculatedWidth = width;
    	}
    	else {
    		width = this.calculatedWidth;
    		
    		if (this.fakeElement.offsetWidth == 0) width = this.calculatedWidth;
    		else if (width <= this.fakeElement.offsetWidth) width = this.fakeElement.offsetWidth;
    		else if (width <= this.fakeElement.offsetWidth * 2) width = this.calculatedWidth;
    		else width = this.fakeElement.offsetWidth * 2;
    	}
    	
        this.selectDrop.style.width = width + 'px';
    	
    	for(var i = 0; i < children.length; i++) {
    		children[i].style.width = width + 'px';
    	}
    	if (width > this.fakeElement.offsetWidth) {
    		if (width + ofs.left > jcf.lib.getWindowWidth()) {
    			ofs.left = ofs.left - (width - this.fakeElement.offsetWidth);
    			this.selectDrop.style.left = ofs.left + 'px';
    		}
    	}
    },
    showDropdown: function () {
        document.body.appendChild(this.selectDrop);
        jcf.lib.removeClass(this.selectDrop, this.options.dropHiddenClass);
        jcf.lib.addClass(this.fakeElement, this.options.dropActiveClass);
        this.positionDropdown();

        // highlight current active item
        var activeItem = this.getFakeActiveOption();
        this.removeClassFromItems(this.options.currentSelectedClass);
        jcf.lib.addClass(activeItem, this.options.currentSelectedClass);

        // show current dropdown
        jcf.lib.event.add(window, 'resize', this.onResizeWindow, this);
        jcf.lib.event.add(window, 'scroll', this.onScrollWindow, this);
        jcf.lib.event.add(document, jcf.eventPress, this.onClickOutside, this);
        this.positionDropdown();
    },
    hideDropdown: function (partial) {
        if (this.selectDrop.parentNode) {
            if (this.selectDrop.offsetWidth) {
                this.selectDrop.parentNode.removeChild(this.selectDrop);
            }
            if (partial) {
                return;
            }
        }
        if (typeof this.origSelectedIndex === 'number') {
            this.realElement.selectedIndex = this.origSelectedIndex;
        }
        jcf.lib.removeClass(this.fakeElement, this.options.dropActiveClass);
        jcf.lib.addClass(this.selectDrop, this.options.dropHiddenClass);
        jcf.lib.event.remove(window, 'resize', this.onResizeWindow);
        jcf.lib.event.remove(window, 'scroll', this.onScrollWindow);
        jcf.lib.event.remove(document.documentElement, jcf.eventPress, this.onClickOutside);
        if (jcf.isTouchDevice) {
            this.onBlur();
        }
    },
    toggleDropdown: function () {
        if (!this.realElement.disabled) {
            if (jcf.isTouchDevice) {
                this.onFocus();
            } else {
                this.realElement.focus();
            }
            this.dropOpened = true;
            if (this.isActiveDrop()) {
                this.hideDropdown();
            } else {
                this.showDropdown();
            }
            this.refreshState();
        }
    },
    scrollToItem: function () {
        if (this.isActiveDrop()) {
            var dropHeight = this.selectList.offsetHeight;
            var offsetTop = this.calcOptionOffset(this.getFakeActiveOption());
            var sTop = this.selectList.scrollTop;
            var oHeight = this.getFakeActiveOption().offsetHeight;
            //offsetTop+=sTop;

            if (offsetTop >= sTop + dropHeight) {
                this.selectList.scrollTop = offsetTop - dropHeight + oHeight;
            } else if (offsetTop < sTop) {
                this.selectList.scrollTop = offsetTop;
            }
        }
    },
    getFakeActiveOption: function (c) {
        return jcf.lib.queryBySelector('li[rel="' + (typeof c === 'number' ? c : this.realElement.selectedIndex) + '"]', this.selectList)[0];
    },
    calcOptionOffset: function (fake) {
        var h = 0;
        var els = jcf.lib.queryBySelector('.jcfcalc', this.selectList);
        for (var i = 0; i < els.length; i++) {
            if (els[i] == fake) break;
            h += els[i].offsetHeight;
        }
        return h;
    },
    childrenHasItem: function (hold, item) {
        var items = hold.getElementsByTagName('*');
        for (i = 0; i < items.length; i++) {
            if (items[i] == item) return true;
        }

        return false;
    },
    removeClassFromItems: function (className) {
        var children = jcf.lib.queryBySelector('li', this.selectList);
        for (var i = children.length - 1; i >= 0; i--) {
            jcf.lib.removeClass(children[i], className);
        }
    },
    setSelectedClass: function (c) {
        jcf.lib.addClass(this.getFakeActiveOption(c), this.options.selectedClass);
    },
    refreshSelectedClass: function (c) {
        if (!this.options.showNativeDrop) {
            this.removeClassFromItems(this.options.selectedClass);
            this.setSelectedClass(c);
        }
        if (this.realElement.disabled) {
            jcf.lib.addClass(this.fakeElement, this.options.disabledClass);
            if (this.labelFor) {
                jcf.lib.addClass(this.labelFor, this.options.labelDisabledClass);
            }
        } else {
            jcf.lib.removeClass(this.fakeElement, this.options.disabledClass);
            if (this.labelFor) {
                jcf.lib.removeClass(this.labelFor, this.options.labelDisabledClass);
            }
        }
    },
    refreshSelectedText: function () {
        if (!this.dropOpened && this.realElement.title) {
            this.valueText.innerHTML = this.realElement.title;
        } else {
            if (this.realElement.options[this.realElement.selectedIndex].title) {
                var optImage = this.parseOptionTitle(this.realElement.options[this.realElement.selectedIndex].title);
                this.valueText.innerHTML = (optImage ? '<img src="' + optImage + '" alt="" />' : '') + this.realElement.options[this.realElement.selectedIndex].innerHTML;
            } else {
                this.valueText.innerHTML = this.realElement.options[this.realElement.selectedIndex].innerHTML;
            }
        }
    },
    refreshState: function () {
        this.origSelectedIndex = this.realElement.selectedIndex;
        this.refreshSelectedClass();
        this.refreshSelectedText();
        if (!this.options.showNativeDrop) {
            this.positionDropdown();
            if (this.selectDrop.offsetWidth) {
                this.scrollToItem();
            }
        }
    }
});

// custom select module
jcf.addModule({
    name: 'select',
    selector: 'select:not(.editable-select)',
    defaultOptions: {
        hideDropOnScroll: true,
        showNativeDrop: false,
        handleDropPosition: true,
        selectDropPosition: 'bottom', // or 'top'
        wrapperClass: 'select-area',
        focusClass: 'select-focus',
        dropActiveClass: 'select-active',
        selectedClass: 'item-selected',
        currentSelectedClass: 'current-selected',
        disabledClass: 'select-disabled',
        valueSelector: 'span.center',
        optGroupClass: 'optgroup',
        openerSelector: 'a.select-opener',
        selectStructure: '<span class="left"></span><span class="center"></span><a class="select-opener"></a>',
        classPrefix: 'select-',
        dropMaxHeight: 200,
        dropFlippedClass: 'select-options-flipped',
        dropHiddenClass: 'options-hidden',
        dropScrollableClass: 'options-overflow',
        dropClass: 'select-options',
        dropClassPrefix: 'drop-',
        dropStructure: '<div class="drop-holder"><div class="drop-list"></div></div>',
        dropSelector: 'div.drop-list'
    },
    checkElement: function (el) {
        return (!el.size && !el.multiple);
    },
    setupWrapper: function () {

        jcf.lib.addClass(this.fakeElement, this.options.wrapperClass);
        this.realElement.parentNode.insertBefore(this.fakeElement, this.realElement);
        this.fakeElement.innerHTML = this.options.selectStructure;
        this.fakeElement.style.width = (this.realElement.offsetWidth > 0 ? this.realElement.offsetWidth + 'px' : 'auto');

        // show native drop if specified in options
        if (jcf.isTouchDevice && jcf.baseOptions.useNativeDropOnMobileDevices) {
            this.options.showNativeDrop = true;
        }
        if (this.options.showNativeDrop) {
            this.fakeElement.appendChild(this.realElement);
            jcf.lib.removeClass(this.realElement, this.options.hiddenClass);
            jcf.lib.setStyles(this.realElement, {
                top: 0,
                left: 0,
                margin: 0,
                padding: 0,
                opacity: 0,
                border: 'none',
                position: 'absolute',
                width: jcf.lib.getInnerWidth(this.fakeElement) - 1,
                height: jcf.lib.getInnerHeight(this.fakeElement) - 1
            });
        }

        // create select body
        this.opener = jcf.lib.queryBySelector(this.options.openerSelector, this.fakeElement)[0];
        this.valueText = jcf.lib.queryBySelector(this.options.valueSelector, this.fakeElement)[0];
        jcf.lib.disableTextSelection(this.valueText);
        this.opener.jcf = this;
    	
		this.valueText.style.width = $(this.fakeElement).width() - $(this.opener).width() + 'px';
        if (!this.options.showNativeDrop) {
            this.createDropdown();
            this.refreshState();
            this.onControlReady(this);
            this.hideDropdown(true);
        } else {
            this.refreshState();
        }
        this.addEvents();
    },
    addEvents: function () {
        if (this.options.showNativeDrop) {
            jcf.lib.event.add(this.realElement, 'click', this.onChange, this);
        } else {
            jcf.lib.event.add(this.fakeElement, 'click', this.toggleDropdown, this);
        }
        jcf.lib.event.add(this.realElement, 'change', this.onChange, this);
    },
    onFakeClick: function () {
        // do nothing (drop toggles by toggleDropdown method)
    },
    onFocus: function () {
        jcf.modules[this.name].superclass.onFocus.apply(this, arguments);
        if (!this.options.showNativeDrop) {
            // Mac Safari Fix
            if (jcf.lib.browser.safariMac) {
                this.realElement.setAttribute('size', '2');
            }
            jcf.lib.event.add(this.realElement, 'keydown', this.onKeyDown, this);
            if (jcf.activeControl && jcf.activeControl != this) {
                jcf.activeControl.hideDropdown();
                jcf.activeControl = this;
            }
        }
    },
    onBlur: function () {
        if (!this.options.showNativeDrop) {
            // Mac Safari Fix
            if (jcf.lib.browser.safariMac) {
                this.realElement.removeAttribute('size');
            }
            if (!this.isActiveDrop() || !this.isOverDrop()) {
                jcf.modules[this.name].superclass.onBlur.apply(this);
                if (jcf.activeControl === this) jcf.activeControl = null;
                if (!jcf.isTouchDevice) {
                    this.hideDropdown();
                }
            }
            jcf.lib.event.remove(this.realElement, 'keydown', this.onKeyDown);
        } else {
            jcf.modules[this.name].superclass.onBlur.apply(this);
        }
    },
    onChange: function () {
        this.refreshState();
    },
    onKeyDown: function (e) {
        jcf.tmpFlag = true;
        setTimeout(function () { jcf.tmpFlag = false }, 100);
        var context = this;
        context.keyboardFix = true;
        setTimeout(function () {
            context.refreshState();
        }, 10);
        if (e.keyCode == 13) {
            context.toggleDropdown.apply(context);
            return false;
        }
    },
    onResizeWindow: function (e) {
        if (this.isActiveDrop()) {
            this.hideDropdown();
        }
    },
    onScrollWindow: function (e) {
        if (this.options.hideDropOnScroll) {
            this.hideDropdown();
        } else if (this.isActiveDrop()) {
            this.positionDropdown();
        }
    },
    onOptionClick: function (e) {
        var opener = e.target && e.target.tagName && e.target.tagName.toLowerCase() == 'li' ? e.target : jcf.lib.getParent(e.target, 'li');
        if (opener) {
            this.realElement.selectedIndex = parseInt(opener.getAttribute('rel'));
            if (jcf.isTouchDevice) {
                this.onFocus();
            } else {
                this.realElement.focus();
            }
            this.refreshState();
            this.hideDropdown();
            jcf.lib.fireEvent(this.realElement, 'change');
        }
        return false;
    },
    onClickOutside: function (e) {
        if (jcf.tmpFlag) {
            jcf.tmpFlag = false;
            return;
        }
        if (!jcf.lib.isParent(this.fakeElement, e.target) && !jcf.lib.isParent(this.selectDrop, e.target)) {
            this.hideDropdown();
        }
    },
    onDropHover: function (e) {
        if (!this.keyboardFix) {
            this.hoverFlag = true;
            var opener = e.target && e.target.tagName && e.target.tagName.toLowerCase() == 'li' ? e.target : jcf.lib.getParent(e.target, 'li');
            if (opener) {
                this.realElement.selectedIndex = parseInt(opener.getAttribute('rel'));
                this.refreshSelectedClass(parseInt(opener.getAttribute('rel')));
            }
        } else {
            this.keyboardFix = false;
        }
    },
    onDropLeave: function () {
        this.hoverFlag = false;
    },
    isActiveDrop: function () {
        return !jcf.lib.hasClass(this.selectDrop, this.options.dropHiddenClass);
    },
    isOverDrop: function () {
        return this.hoverFlag;
    },
    createDropdown: function () {
        // remove old dropdown if exists
        if (this.selectDrop) {
            this.selectDrop.parentNode.removeChild(this.selectDrop);
        }

        // create dropdown holder
        this.selectDrop = document.createElement('div');
        this.selectDrop.className = this.options.dropClass;
        this.selectDrop.innerHTML = this.options.dropStructure;
        jcf.lib.setStyles(this.selectDrop, { position: 'absolute' });
        this.selectList = jcf.lib.queryBySelector(this.options.dropSelector, this.selectDrop)[0];
        jcf.lib.addClass(this.selectDrop, this.options.dropHiddenClass);
        document.body.appendChild(this.selectDrop);
        this.selectDrop.jcf = this;
        jcf.lib.event.add(this.selectDrop, 'click', this.onOptionClick, this);
        jcf.lib.event.add(this.selectDrop, 'mouseover', this.onDropHover, this);
        jcf.lib.event.add(this.selectDrop, 'mouseout', this.onDropLeave, this);
        this.buildDropdown();
    },
    buildDropdown: function () {
        // build select options / optgroups
        this.buildDropdownOptions();

        // position and resize dropdown
        this.positionDropdown();

        // cut dropdown if height exceedes
        this.buildDropdownScroll();
    },
    buildDropdownOptions: function () {
        this.resStructure = '';
        this.optNum = 0;
        for (var i = 0; i < this.realElement.children.length; i++) {
            this.resStructure += this.buildElement(this.realElement.children[i]) + '\n';
        }
        this.selectList.innerHTML = this.resStructure;
    },
    buildDropdownScroll: function () {
        if (this.options.dropMaxHeight) {
            if (this.selectDrop.offsetHeight > this.options.dropMaxHeight) {
                this.selectList.style.height = this.options.dropMaxHeight + 'px';
                this.selectList.style.overflow = 'auto';
                this.selectList.style.overflowX = 'hidden';
                jcf.lib.addClass(this.selectDrop, this.options.dropScrollableClass);
            }
        }
        ////alert('h: ' + this.selectList.style.height);
        jcf.lib.addClass(this.selectDrop, jcf.lib.getAllClasses(this.realElement.className, this.options.dropClassPrefix, jcf.baseOptions.hiddenClass));
    },
    parseOptionTitle: function (optTitle) {
        return (typeof optTitle === 'string' && /\.(jpg|gif|png|bmp|jpeg)(.*)?$/i.test(optTitle)) ? optTitle : '';
    },
    buildElement: function (obj) {
        // build option
        var res = '', optImage;
        if (obj.tagName.toLowerCase() == 'option') {
            if (!jcf.lib.prevSibling(obj) || jcf.lib.prevSibling(obj).tagName.toLowerCase() != 'option') {
                res += '<ul>';
            }

            optImage = this.parseOptionTitle(obj.title);
            res += '<li rel="' + (this.optNum++) + '" class="' + (obj.className ? obj.className + ' ' : '') + 'jcfcalc"><a href="#">' + (optImage ? '<img src="' + optImage + '" alt="" />' : '') + '<span>' + obj.innerHTML + '</span></a></li>';
            if (!jcf.lib.nextSibling(obj) || jcf.lib.nextSibling(obj).tagName.toLowerCase() != 'option') {
                res += '</ul>';
            }
            return res;
        }
        // build option group with options
        else if (obj.tagName.toLowerCase() == 'optgroup' && obj.label) {
            res += '<div class="' + this.options.optGroupClass + '">';
            res += '<strong class="jcfcalc"><em>' + (obj.label) + '</em></strong>';
            for (var i = 0; i < obj.children.length; i++) {
                res += this.buildElement(obj.children[i]);
            }
            res += '</div>';
            return res;
        }
    },
    positionDropdown: function () {
        var ofs = jcf.lib.getOffset(this.fakeElement), selectAreaHeight = this.fakeElement.offsetHeight, selectDropHeight = this.selectDrop.offsetHeight;
        var fitInTop = ofs.top - selectDropHeight >= jcf.lib.getScrollTop() && jcf.lib.getScrollTop() + jcf.lib.getWindowHeight() < ofs.top + selectAreaHeight + selectDropHeight;


        if ((this.options.handleDropPosition && fitInTop) || this.options.selectDropPosition === 'top') {
            this.selectDrop.style.top = (ofs.top - selectDropHeight) + 'px';
            jcf.lib.addClass(this.selectDrop, this.options.dropFlippedClass);
        } else {
            this.selectDrop.style.top = (ofs.top + selectAreaHeight) + 'px';
            jcf.lib.removeClass(this.selectDrop, this.options.dropFlippedClass);
        }
        this.selectDrop.style.left = ofs.left + 'px';

    	var width = 0;
    	var children = jcf.lib.queryBySelector('li', this.selectList);
    	if (this.calculatedWidth == 0 || this.calculatedWidth == null) {
    		
    		var itemMaxWidth = 0;    		
    		for(var i = 0; i < children.length; i++) {
    			if (itemMaxWidth < children[i].offsetWidth) itemMaxWidth = children[i].offsetWidth;
    		}
    	    if (this.options.dropMaxHeight) {
    			if (this.selectDrop.offsetHeight > this.options.dropMaxHeight) {
    				var wide_scroll_html = '<div id="wide_scroll_div_one" style="width:50px;height:50px;overflow-y:scroll;position:absolute;top:-200px;left:-200px;"><div id="wide_scroll_div_two" style="height:100px;width:100%"></div></div>'; 
					$("body").append(wide_scroll_html); // Append our div and add the hmtl to your document for calculations
					var scroll_w1 = $("#wide_scroll_div_one").width(); // Getting the width of the surrounding(parent) div - we already know it is 50px since we styled it but just to make sure.
					var scroll_w2 = $("#wide_scroll_div_two").innerWidth(); // Find the inner width of the inner(child) div.
					var scroll_bar_width = scroll_w1 - scroll_w2; // subtract the difference
					$("#wide_scroll_div_one").remove(); // remove the html from your document    				
    				itemMaxWidth = itemMaxWidth + scroll_bar_width;
    			}
    		}
    		if (this.fakeElement.offsetWidth == 0) width = itemMaxWidth;
    		else if (itemMaxWidth <= this.fakeElement.offsetWidth) width = this.fakeElement.offsetWidth;
    		else if (itemMaxWidth <= this.fakeElement.offsetWidth * 2) width = itemMaxWidth;
    		else width = this.fakeElement.offsetWidth * 2;
    		
    		this.calculatedWidth = width;
    	}
    	else {
    		width = this.calculatedWidth;
    		
    		if (this.fakeElement.offsetWidth == 0) width = this.calculatedWidth;
    		else if (width <= this.fakeElement.offsetWidth) width = this.fakeElement.offsetWidth;
    		else if (width <= this.fakeElement.offsetWidth * 2) width = this.calculatedWidth;
    		else width = this.fakeElement.offsetWidth * 2;
    	}
    	
        this.selectDrop.style.width = width + 'px';
    	
    	for(var i = 0; i < children.length; i++) {
    		children[i].style.width = width + 'px';
    	}
    	if (width > this.fakeElement.offsetWidth) {
    		if (width + ofs.left > jcf.lib.getWindowWidth()) {
    			ofs.left = ofs.left - (width - this.fakeElement.offsetWidth);
    			this.selectDrop.style.left = ofs.left + 'px';
    		}
    	}
    },
    showDropdown: function () {
        document.body.appendChild(this.selectDrop);
        jcf.lib.removeClass(this.selectDrop, this.options.dropHiddenClass);
        jcf.lib.addClass(this.fakeElement, this.options.dropActiveClass);
        this.positionDropdown();

        // highlight current active item
        var activeItem = this.getFakeActiveOption();
        this.removeClassFromItems(this.options.currentSelectedClass);
        jcf.lib.addClass(activeItem, this.options.currentSelectedClass);

        // show current dropdown
        jcf.lib.event.add(window, 'resize', this.onResizeWindow, this);
        jcf.lib.event.add(window, 'scroll', this.onScrollWindow, this);
        jcf.lib.event.add(document, jcf.eventPress, this.onClickOutside, this);
        this.positionDropdown();
    },
    hideDropdown: function (partial) {
        if (this.selectDrop.parentNode) {
            if (this.selectDrop.offsetWidth) {
                this.selectDrop.parentNode.removeChild(this.selectDrop);
            }
            if (partial) {
                return;
            }
        }
        if (typeof this.origSelectedIndex === 'number') {
            this.realElement.selectedIndex = this.origSelectedIndex;
        }
        jcf.lib.removeClass(this.fakeElement, this.options.dropActiveClass);
        jcf.lib.addClass(this.selectDrop, this.options.dropHiddenClass);
        jcf.lib.event.remove(window, 'resize', this.onResizeWindow);
        jcf.lib.event.remove(window, 'scroll', this.onScrollWindow);
        jcf.lib.event.remove(document.documentElement, jcf.eventPress, this.onClickOutside);
        if (jcf.isTouchDevice) {
            this.onBlur();
        }
    },
    toggleDropdown: function () {
        if (!this.realElement.disabled) {
            if (jcf.isTouchDevice) {
                this.onFocus();
            } else {
                this.realElement.focus();
            }
            this.dropOpened = true;
            if (this.isActiveDrop()) {
                this.hideDropdown();
            } else {
                this.showDropdown();
            }
            this.refreshState();
        }
    },
    scrollToItem: function () {
        if (this.isActiveDrop()) {
            try {
                var dropHeight = this.selectList.offsetHeight;
                var offsetTop = this.calcOptionOffset(this.getFakeActiveOption());
                var sTop = this.selectList.scrollTop;
                var oHeight = this.getFakeActiveOption().offsetHeight;
                //offsetTop+=sTop;

                if (offsetTop >= sTop + dropHeight) {
                    this.selectList.scrollTop = offsetTop - dropHeight + oHeight;
                } else if (offsetTop < sTop) {
                    this.selectList.scrollTop = offsetTop;
                }
            }
            catch (e) {
            }
        }
    },
    getFakeActiveOption: function (c) {
        return jcf.lib.queryBySelector('li[rel="' + (typeof c === 'number' ? c : this.realElement.selectedIndex) + '"]', this.selectList)[0];
    },
    calcOptionOffset: function (fake) {
        var h = 0;
        var els = jcf.lib.queryBySelector('.jcfcalc', this.selectList);
        for (var i = 0; i < els.length; i++) {
            if (els[i] == fake) break;
            h += els[i].offsetHeight;
        }
        return h;
    },
    childrenHasItem: function (hold, item) {
        var items = hold.getElementsByTagName('*');
        for (i = 0; i < items.length; i++) {
            if (items[i] == item) return true;
        }
        return false;
    },
    removeClassFromItems: function (className) {
        var children = jcf.lib.queryBySelector('li', this.selectList);
        for (var i = children.length - 1; i >= 0; i--) {
            jcf.lib.removeClass(children[i], className);
        }
    },
    setSelectedClass: function (c) {
        jcf.lib.addClass(this.getFakeActiveOption(c), this.options.selectedClass);
    },
    refreshSelectedClass: function (c) {
        if (!this.options.showNativeDrop) {
            this.removeClassFromItems(this.options.selectedClass);
            this.setSelectedClass(c);
        }
        if (this.realElement.disabled) {
            jcf.lib.addClass(this.fakeElement, this.options.disabledClass);
            if (this.labelFor) {
                jcf.lib.addClass(this.labelFor, this.options.labelDisabledClass);
            }
        } else {
            jcf.lib.removeClass(this.fakeElement, this.options.disabledClass);
            if (this.labelFor) {
                jcf.lib.removeClass(this.labelFor, this.options.labelDisabledClass);
            }
        }
    },
    refreshSelectedText: function () {
        if (!this.dropOpened && this.realElement.title) {
            this.valueText.innerHTML = this.realElement.title;
        } else {
            if (this.realElement != undefined
                && this.realElement != undefined
                && this.realElement.options != undefined
                && this.realElement.options[this.realElement.selectedIndex] != undefined
                && this.realElement.options[this.realElement.selectedIndex].title) {
                var optImage = this.parseOptionTitle(this.realElement.options[this.realElement.selectedIndex].title);
                this.valueText.innerHTML = (optImage ? '<img src="' + optImage + '" alt="" />' : '') + this.realElement.options[this.realElement.selectedIndex].innerHTML;
            } else {
                if (this.realElement != undefined
                && this.realElement != undefined
                && this.realElement.options != undefined
                && this.realElement.options[this.realElement.selectedIndex] != undefined)
                    this.valueText.innerHTML = this.realElement.options[this.realElement.selectedIndex].innerHTML;
            }
        }
    },
    refreshState: function () {
        this.origSelectedIndex = this.realElement.selectedIndex;
        this.refreshSelectedClass();
        this.refreshSelectedText();
        if (!this.options.showNativeDrop) {
            this.positionDropdown();
            if (this.selectDrop.offsetWidth) {
                this.scrollToItem();
            }
        }
    }
});

/*
// custom checkbox module
jcf.addModule({
    name: 'checkbox',
    selector: 'input[type="checkbox"]',
    defaultOptions: {
        wrapperClass: 'chk-area',
        focusClass: 'chk-focus',
        checkedClass: 'chk-checked',
        labelActiveClass: 'chk-label-active',
        uncheckedClass: 'chk-unchecked',
        disabledClass: 'chk-disabled',
        chkStructure: '<span></span>'
    }
});
*/

// mobile browsers detect
browserPlatform = {
    platforms: [
		{ uaString: ['symbian', 'midp'], cssFile: 'symbian.css' }, // Symbian phones
		{uaString: ['opera', 'mobi'], cssFile: 'opera.css' }, // Opera Mobile
		{uaString: ['msie', 'ppc'], cssFile: 'ieppc.css' }, // IE Mobile <6
		{uaString: 'iemobile', cssFile: 'iemobile.css' }, // IE Mobile 6+
		{uaString: 'webos', cssFile: 'webos.css' }, // Palm WebOS
		{uaString: 'Android', cssFile: 'android.css' }, // Android
		{uaString: ['BlackBerry', '/6.0', 'mobi'], cssFile: 'blackberry6.css' }, // Blackberry 6
		{uaString: ['BlackBerry', '/7.0', 'mobi'], cssFile: 'blackberry7.css' }, // Blackberry 7+
		{uaString: 'ipad', cssFile: 'ipad.css', miscHead: '<meta name="viewport" content="width=950" />' }, // iPad
		{uaString: ['safari', 'mobi'], cssFile: 'safari.css', miscHead: '<meta name="viewport" content="width=950" />'} // iPhone and other webkit browsers
	],
    options: {
        cssPath: 'css/',
        mobileCSS: 'allmobile.css'
    },
    init: function () {
        this.checkMobile();
        this.parsePlatforms();
        return this;
    },
    checkMobile: function () {
        if (this.uaMatch('mobi') || this.uaMatch('midp') || this.uaMatch('ppc') || this.uaMatch('webos')) {
            this.attachStyles({ cssFile: this.options.mobileCSS });
        }
    },
    parsePlatforms: function () {
        for (var i = 0; i < this.platforms.length; i++) {
            if (typeof this.platforms[i].uaString === 'string') {
                if (this.uaMatch(this.platforms[i].uaString)) {
                    this.attachStyles(this.platforms[i]);
                    break;
                }
            } else {
                for (var j = 0, allMatch = true; j < this.platforms[i].uaString.length; j++) {
                    if (!this.uaMatch(this.platforms[i].uaString[j])) {
                        allMatch = false;
                    }
                }
                if (allMatch) {
                    this.attachStyles(this.platforms[i]);
                    break;
                }
            }
        }
    },
    attachStyles: function (platform) {
        var head = document.getElementsByTagName('head')[0], fragment;
        var cssText = '<link rel="stylesheet" href="' + this.options.cssPath + platform.cssFile + '" type="text/css"/>';
        var miscText = platform.miscHead;
        if (platform.cssFile) {
            if (document.body) {
                fragment = document.createElement('div');
                fragment.innerHTML = cssText;
                head.appendChild(fragment.childNodes[0]);
            } else {
                document.write(cssText);
            }
        }
        if (platform.miscHead) {
            if (document.body) {
                fragment = document.createElement('div');
                fragment.innerHTML = miscText;
                head.appendChild(fragment.childNodes[0]);
            } else {
                document.write(miscText);
            }
        }
    },
    uaMatch: function (str) {
        if (!this.ua) {
            this.ua = navigator.userAgent.toLowerCase();
        }
        return this.ua.indexOf(str.toLowerCase()) != -1;
    }
}.init();



/*
  jQuery Tooltip - Dimensions
*/
(function($){

// store a copy of the core height and width methods
var height = $.fn.height,
    width  = $.fn.width;

$.fn.extend({
	/**
	 * If used on document, returns the document's height (innerHeight)
	 * If used on window, returns the viewport's (window) height
	 * See core docs on height() to see what happens when used on an element.
	 *
	 * @example $("#testdiv").height()
	 * @result 200
	 *
	 * @example $(document).height()
	 * @result 800
	 *
	 * @example $(window).height()
	 * @result 400
	 *
	 * @name height
	 * @type Object
	 * @cat Plugins/Dimensions
	 */
	height: function() {
		if ( this[0] == window )
			return self.innerHeight ||
				$.boxModel && document.documentElement.clientHeight || 
				document.body.clientHeight;
		
		if ( this[0] == document )
			return Math.max( document.body.scrollHeight, document.body.offsetHeight );
		
		return height.apply(this, arguments);
	},
	
	/**
	 * If used on document, returns the document's width (innerWidth)
	 * If used on window, returns the viewport's (window) width
	 * See core docs on height() to see what happens when used on an element.
	 *
	 * @example $("#testdiv").width()
	 * @result 200
	 *
	 * @example $(document).width()
	 * @result 800
	 *
	 * @example $(window).width()
	 * @result 400
	 *
	 * @name width
	 * @type Object
	 * @cat Plugins/Dimensions
	 */
	width: function() {
		if ( this[0] == window )
			return self.innerWidth ||
				$.boxModel && document.documentElement.clientWidth ||
				document.body.clientWidth;

		if ( this[0] == document )
			return Math.max( document.body.scrollWidth, document.body.offsetWidth );

		return width.apply(this, arguments);
	},
	
	/**
	 * Returns the inner height value (without border) for the first matched element.
	 * If used on document, returns the document's height (innerHeight)
	 * If used on window, returns the viewport's (window) height
	 *
	 * @example $("#testdiv").innerHeight()
	 * @result 800
	 *
	 * @name innerHeight
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	innerHeight: function() {
		return this[0] == window || this[0] == document ?
			this.height() :
			this.is(':visible') ?
				this[0].offsetHeight - num(this, 'borderTopWidth') - num(this, 'borderBottomWidth') :
				this.height() + num(this, 'paddingTop') + num(this, 'paddingBottom');
	},
	
	/**
	 * Returns the inner width value (without border) for the first matched element.
	 * If used on document, returns the document's Width (innerWidth)
	 * If used on window, returns the viewport's (window) width
	 *
	 * @example $("#testdiv").innerWidth()
	 * @result 1000
	 *
	 * @name innerWidth
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	innerWidth: function() {
		return this[0] == window || this[0] == document ?
			this.width() :
			this.is(':visible') ?
				this[0].offsetWidth - num(this, 'borderLeftWidth') - num(this, 'borderRightWidth') :
				this.width() + num(this, 'paddingLeft') + num(this, 'paddingRight');
	},
	
	/**
	 * Returns the outer height value (including border) for the first matched element.
	 * Cannot be used on document or window.
	 *
	 * @example $("#testdiv").outerHeight()
	 * @result 1000
	 *
	 * @name outerHeight
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	outerHeight: function() {
		return this[0] == window || this[0] == document ?
			this.height() :
			this.is(':visible') ?
				this[0].offsetHeight :
				this.height() + num(this,'borderTopWidth') + num(this, 'borderBottomWidth') + num(this, 'paddingTop') + num(this, 'paddingBottom');
	},
	
	/**
	 * Returns the outer width value (including border) for the first matched element.
	 * Cannot be used on document or window.
	 *
	 * @example $("#testdiv").outerHeight()
	 * @result 1000
	 *
	 * @name outerHeight
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	outerWidth: function() {
		return this[0] == window || this[0] == document ?
			this.width() :
			this.is(':visible') ?
				this[0].offsetWidth :
				this.width() + num(this, 'borderLeftWidth') + num(this, 'borderRightWidth') + num(this, 'paddingLeft') + num(this, 'paddingRight');
	},
	
	/**
	 * Returns how many pixels the user has scrolled to the right (scrollLeft).
	 * Works on containers with overflow: auto and window/document.
	 *
	 * @example $("#testdiv").scrollLeft()
	 * @result 100
	 *
	 * @name scrollLeft
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	/**
	 * Sets the scrollLeft property and continues the chain.
	 * Works on containers with overflow: auto and window/document.
	 *
	 * @example $("#testdiv").scrollLeft(10).scrollLeft()
	 * @result 10
	 *
	 * @name scrollLeft
	 * @param Number value A positive number representing the desired scrollLeft.
	 * @type jQuery
	 * @cat Plugins/Dimensions
	 */
	scrollLeft: function(val) {
		if ( val != undefined )
			// set the scroll left
			return this.each(function() {
				if (this == window || this == document)
					window.scrollTo( val, $(window).scrollTop() );
				else
					this.scrollLeft = val;
			});
		
		// return the scroll left offest in pixels
		if ( this[0] == window || this[0] == document )
			return self.pageXOffset ||
				$.boxModel && document.documentElement.scrollLeft ||
				document.body.scrollLeft;
				
		return this[0].scrollLeft;
	},
	
	/**
	 * Returns how many pixels the user has scrolled to the bottom (scrollTop).
	 * Works on containers with overflow: auto and window/document.
	 *
	 * @example $("#testdiv").scrollTop()
	 * @result 100
	 *
	 * @name scrollTop
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	/**
	 * Sets the scrollTop property and continues the chain.
	 * Works on containers with overflow: auto and window/document.
	 *
	 * @example $("#testdiv").scrollTop(10).scrollTop()
	 * @result 10
	 *
	 * @name scrollTop
	 * @param Number value A positive number representing the desired scrollTop.
	 * @type jQuery
	 * @cat Plugins/Dimensions
	 */
	scrollTop: function(val) {
		if ( val != undefined )
			// set the scroll top
			return this.each(function() {
				if (this == window || this == document)
					window.scrollTo( $(window).scrollLeft(), val );
				else
					this.scrollTop = val;
			});
		
		// return the scroll top offset in pixels
		if ( this[0] == window || this[0] == document )
			return self.pageYOffset ||
				$.boxModel && document.documentElement.scrollTop ||
				document.body.scrollTop;

		return this[0].scrollTop;
	},
	
	/** 
	 * Returns the top and left positioned offset in pixels.
	 * The positioned offset is the offset between a positioned
	 * parent and the element itself.
	 *
	 * @example $("#testdiv").position()
	 * @result { top: 100, left: 100 }
	 * 
	 * @name position
	 * @param Map options Optional settings to configure the way the offset is calculated.
	 * @option Boolean margin Should the margin of the element be included in the calculations? False by default.
	 * @option Boolean border Should the border of the element be included in the calculations? False by default.
	 * @option Boolean padding Should the padding of the element be included in the calculations? False by default.
	 * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the
	 *                            chain will not be broken and the result will be assigned to this object.
	 * @type Object
	 * @cat Plugins/Dimensions
	 */
	position: function(options, returnObject) {
		var elem = this[0], parent = elem.parentNode, op = elem.offsetParent,
		    options = $.extend({ margin: false, border: false, padding: false, scroll: false }, options || {}),
			x = elem.offsetLeft,
			y = elem.offsetTop, 
			sl = elem.scrollLeft, 
			st = elem.scrollTop;
			
		// Mozilla and IE do not add the border
		if ($.browser.mozilla || $.browser.msie) {
			// add borders to offset
			x += num(elem, 'borderLeftWidth');
			y += num(elem, 'borderTopWidth');
		}

		if ($.browser.mozilla) {
			do {
				// Mozilla does not add the border for a parent that has overflow set to anything but visible
				if ($.browser.mozilla && parent != elem && $.css(parent, 'overflow') != 'visible') {
					x += num(parent, 'borderLeftWidth');
					y += num(parent, 'borderTopWidth');
				}

				if (parent == op) break; // break if we are already at the offestParent
			} while ((parent = parent.parentNode) && (parent.tagName.toLowerCase() != 'body' || parent.tagName.toLowerCase() != 'html'));
		}
		
		var returnValue = handleOffsetReturn(elem, options, x, y, sl, st);
		
		if (returnObject) { $.extend(returnObject, returnValue); return this; }
		else              { return returnValue; }
	},
	
	/**
	 * Returns the location of the element in pixels from the top left corner of the viewport.
	 *
	 * For accurate readings make sure to use pixel values for margins, borders and padding.
	 * 
	 * Known issues:
	 *  - Issue: A div positioned relative or static without any content before it and its parent will report an offsetTop of 0 in Safari
	 *    Workaround: Place content before the relative div ... and set height and width to 0 and overflow to hidden
	 *
	 * @example $("#testdiv").offset()
	 * @result { top: 100, left: 100, scrollTop: 10, scrollLeft: 10 }
	 *
	 * @example $("#testdiv").offset({ scroll: false })
	 * @result { top: 90, left: 90 }
	 *
	 * @example var offset = {}
	 * $("#testdiv").offset({ scroll: false }, offset)
	 * @result offset = { top: 90, left: 90 }
	 *
	 * @name offset
	 * @param Map options Optional settings to configure the way the offset is calculated.
	 * @option Boolean margin Should the margin of the element be included in the calculations? True by default.
	 * @option Boolean border Should the border of the element be included in the calculations? False by default.
	 * @option Boolean padding Should the padding of the element be included in the calculations? False by default.
	 * @option Boolean scroll Should the scroll offsets of the parent elements be included in the calculations? True by default.
	 *                        When true it adds the totla scroll offets of all parents to the total offset and also adds two properties
	 *                        to the returned object, scrollTop and scrollLeft. 
	 * @options Boolean lite Will use offsetLite instead of offset when set to true. False by default.
	 * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the
	 *                            chain will not be broken and the result will be assigned to this object.
	 * @type Object
	 * @cat Plugins/Dimensions
	 */
	offset: function(options, returnObject) {
		var x = 0, y = 0, sl = 0, st = 0,
		    elem = this[0], parent = this[0], op, parPos, elemPos = $.css(elem, 'position'),
		    mo = $.browser.mozilla, ie = $.browser.msie, sf = $.browser.safari, oa = $.browser.opera,
		    absparent = false, relparent = false, 
		    options = $.extend({ margin: true, border: false, padding: false, scroll: true, lite: false }, options || {});
		
		// Use offsetLite if lite option is true
		if (options.lite) return this.offsetLite(options, returnObject);
		
		if (elem.tagName.toLowerCase() == 'body') {
			// Safari is the only one to get offsetLeft and offsetTop properties of the body "correct"
			// Except they all mess up when the body is positioned absolute or relative
			x = elem.offsetLeft;
			y = elem.offsetTop;
			// Mozilla ignores margin and subtracts border from body element
			if (mo) {
				x += num(elem, 'marginLeft') + (num(elem, 'borderLeftWidth')*2);
				y += num(elem, 'marginTop')  + (num(elem, 'borderTopWidth') *2);
			} else
			// Opera ignores margin
			if (oa) {
				x += num(elem, 'marginLeft');
				y += num(elem, 'marginTop');
			} else
			// IE does not add the border in Standards Mode
			if (ie && jQuery.boxModel) {
				x += num(elem, 'borderLeftWidth');
				y += num(elem, 'borderTopWidth');
			}
		} else {
			do {
				parPos = $.css(parent, 'position');
			
				x += parent.offsetLeft;
				y += parent.offsetTop;

				// Mozilla and IE do not add the border
				if (mo || ie) {
					// add borders to offset
					x += num(parent, 'borderLeftWidth');
					y += num(parent, 'borderTopWidth');

					// Mozilla does not include the border on body if an element isn't positioned absolute and is without an absolute parent
					if (mo && parPos == 'absolute') absparent = true;
					// IE does not include the border on the body if an element is position static and without an absolute or relative parent
					if (ie && parPos == 'relative') relparent = true;
				}

				op = parent.offsetParent;
				if (options.scroll || mo) {
					do {
						if (options.scroll) {
							// get scroll offsets
							sl += parent.scrollLeft;
							st += parent.scrollTop;
						}
				
						// Mozilla does not add the border for a parent that has overflow set to anything but visible
						if (mo && parent != elem && $.css(parent, 'overflow') != 'visible') {
							x += num(parent, 'borderLeftWidth');
							y += num(parent, 'borderTopWidth');
						}
				
						parent = parent.parentNode;
					} while (parent != op);
				}
				parent = op;

				if (parent.tagName.toLowerCase() == 'body' || parent.tagName.toLowerCase() == 'html') {
					// Safari and IE Standards Mode doesn't add the body margin for elments positioned with static or relative
					if ((sf || (ie && $.boxModel)) && elemPos != 'absolute' && elemPos != 'fixed') {
						x += num(parent, 'marginLeft');
						y += num(parent, 'marginTop');
					}
					// Mozilla does not include the border on body if an element isn't positioned absolute and is without an absolute parent
					// IE does not include the border on the body if an element is positioned static and without an absolute or relative parent
					if ( (mo && !absparent && elemPos != 'fixed') || 
					     (ie && elemPos == 'static' && !relparent) ) {
						x += num(parent, 'borderLeftWidth');
						y += num(parent, 'borderTopWidth');
					}
					break; // Exit the loop
				}
			} while (parent);
		}

		var returnValue = handleOffsetReturn(elem, options, x, y, sl, st);

		if (returnObject) { $.extend(returnObject, returnValue); return this; }
		else              { return returnValue; }
	},
	
	/**
	 * Returns the location of the element in pixels from the top left corner of the viewport.
	 * This method is much faster than offset but not as accurate. This method can be invoked
	 * by setting the lite option to true in the offset method.
	 *
	 * @name offsetLite
	 * @param Map options Optional settings to configure the way the offset is calculated.
	 * @option Boolean margin Should the margin of the element be included in the calculations? True by default.
	 * @option Boolean border Should the border of the element be included in the calculations? False by default.
	 * @option Boolean padding Should the padding of the element be included in the calculations? False by default.
	 * @option Boolean scroll Should the scroll offsets of the parent elements be included in the calculations? True by default.
	 *                        When true it adds the totla scroll offets of all parents to the total offset and also adds two properties
	 *                        to the returned object, scrollTop and scrollLeft. 
	 * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the
	 *                            chain will not be broken and the result will be assigned to this object.
	 * @type Object
	 * @cat Plugins/Dimensions
	 */
	offsetLite: function(options, returnObject) {
		var x = 0, y = 0, sl = 0, st = 0, parent = this[0], op, 
		    options = $.extend({ margin: true, border: false, padding: false, scroll: true }, options || {});
				
		do {
			x += parent.offsetLeft;
			y += parent.offsetTop;

			op = parent.offsetParent;
			if (options.scroll) {
				// get scroll offsets
				do {
					sl += parent.scrollLeft;
					st += parent.scrollTop;
					parent = parent.parentNode;
				} while(parent != op);
			}
			parent = op;
		} while (parent && parent.tagName.toLowerCase() != 'body' && parent.tagName.toLowerCase() != 'html');

		var returnValue = handleOffsetReturn(this[0], options, x, y, sl, st);

		if (returnObject) { $.extend(returnObject, returnValue); return this; }
		else              { return returnValue; }
	}
});

/**
 * Handles converting a CSS Style into an Integer.
 * @private
 */
var num = function(el, prop) {
	return parseInt($.css(el.jquery?el[0]:el,prop))||0;
};

/**
 * Handles the return value of the offset and offsetLite methods.
 * @private
 */
var handleOffsetReturn = function(elem, options, x, y, sl, st) {
	if ( !options.margin ) {
		x -= num(elem, 'marginLeft');
		y -= num(elem, 'marginTop');
	}

	// Safari and Opera do not add the border for the element
	if ( options.border && ($.browser.safari || $.browser.opera) ) {
		x += num(elem, 'borderLeftWidth');
		y += num(elem, 'borderTopWidth');
	} else if ( !options.border && !($.browser.safari || $.browser.opera) ) {
		x -= num(elem, 'borderLeftWidth');
		y -= num(elem, 'borderTopWidth');
	}

	if ( options.padding ) {
		x += num(elem, 'paddingLeft');
		y += num(elem, 'paddingTop');
	}
	
	// do not include scroll offset on the element
	if ( options.scroll ) {
		sl -= elem.scrollLeft;
		st -= elem.scrollTop;
	}

	return options.scroll ? { top: y - st, left: x - sl, scrollTop:  st, scrollLeft: sl }
	                      : { top: y, left: x };
};

})(jQuery);

/*
  jQuery Tooltip - BGiframe
*/
(function($){
$.fn.bgIframe = $.fn.bgiframe = function(s) {
	// This is only for IE6
	if ( $.browser.msie && parseInt($.browser.version) <= 6 ) {
		s = $.extend({
			top     : 'auto', // auto == .currentStyle.borderTopWidth
			left    : 'auto', // auto == .currentStyle.borderLeftWidth
			width   : 'auto', // auto == offsetWidth
			height  : 'auto', // auto == offsetHeight
			opacity : true,
			src     : 'javascript:false;'
		}, s || {});
		var prop = function(n){return n&&n.constructor==Number?n+'px':n;},
		    html = '<iframe class="bgiframe"frameborder="0"tabindex="-1"src="'+s.src+'"'+
		               'style="display:block;position:absolute;z-index:-1;'+
			               (s.opacity !== false?'filter:Alpha(Opacity=\'0\');':'')+
					       'top:'+(s.top=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')':prop(s.top))+';'+
					       'left:'+(s.left=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')':prop(s.left))+';'+
					       'width:'+(s.width=='auto'?'expression(this.parentNode.offsetWidth+\'px\')':prop(s.width))+';'+
					       'height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';'+
					'"/>';
		return this.each(function() {
			if ( $('> iframe.bgiframe', this).length == 0 )
				this.insertBefore( document.createElement(html), this.firstChild );
		});
	}
	return this;
};

// Add browser.version if it doesn't exist
if (!$.browser.version)
	$.browser.version = navigator.userAgent.toLowerCase().match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)[1];

})(jQuery);

/*
 * jQuery Tooltip plugin 1.3
 *
 * http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
 * http://docs.jquery.com/Plugins/Tooltip
 *
 * Copyright (c) 2006 - 2008 J�rn Zaefferer
 *
 * $Id: jquery.tooltip.js 5741 2008-06-21 15:22:16Z joern.zaefferer $
 * 
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */;(function($){var helper={},current,title,tID,IE=$.browser.msie&&/MSIE\s(5\.5|6\.)/.test(navigator.userAgent),track=false;$.tooltip={blocked:false,defaults:{delay:200,fade:false,showURL:true,extraClass:"",top:15,left:15,id:"tooltip"},block:function(){$.tooltip.blocked=!$.tooltip.blocked;}};$.fn.extend({tooltip:function(settings){settings=$.extend({},$.tooltip.defaults,settings);createHelper(settings);return this.each(function(){$.data(this,"tooltip",settings);this.tOpacity=helper.parent.css("opacity");this.tooltipText=this.title;$(this).removeAttr("title");this.alt="";}).mouseover(save).mouseout(hide).click(hide);},fixPNG:IE?function(){return this.each(function(){var image=$(this).css('backgroundImage');if(image.match(/^url\(["']?(.*\.png)["']?\)$/i)){image=RegExp.$1;$(this).css({'backgroundImage':'none','filter':"progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='"+image+"')"}).each(function(){var position=$(this).css('position');if(position!='absolute'&&position!='relative')$(this).css('position','relative');});}});}:function(){return this;},unfixPNG:IE?function(){return this.each(function(){$(this).css({'filter':'',backgroundImage:''});});}:function(){return this;},hideWhenEmpty:function(){return this.each(function(){$(this)[$(this).html()?"show":"hide"]();});},url:function(){return this.attr('href')||this.attr('src');}});function createHelper(settings){if(helper.parent)return;helper.parent=$('<div id="'+settings.id+'"><h3></h3><div class="body"></div><div class="url"></div></div>').appendTo(document.body).hide();if($.fn.bgiframe)helper.parent.bgiframe();helper.title=$('h3',helper.parent);helper.body=$('div.body',helper.parent);helper.url=$('div.url',helper.parent);}function settings(element){return $.data(element,"tooltip");}function handle(event){if(settings(this).delay)tID=setTimeout(show,settings(this).delay);else
show();track=!!settings(this).track;$(document.body).bind('mousemove',update);update(event);}function save(){if($.tooltip.blocked||this==current||(!this.tooltipText&&!settings(this).bodyHandler))return;current=this;title=this.tooltipText;if(settings(this).bodyHandler){helper.title.hide();var bodyContent=settings(this).bodyHandler.call(this);if(bodyContent.nodeType||bodyContent.jquery){helper.body.empty().append(bodyContent)}else{helper.body.html(bodyContent);}helper.body.show();}else if(settings(this).showBody){var parts=title.split(settings(this).showBody);helper.title.html(parts.shift()).show();helper.body.empty();for(var i=0,part;(part=parts[i]);i++){if(i>0)helper.body.append("<br/>");helper.body.append(part);}helper.body.hideWhenEmpty();}else{helper.title.html(title).show();helper.body.hide();}if(settings(this).showURL&&$(this).url())helper.url.html($(this).url().replace('http://','')).show();else
helper.url.hide();helper.parent.addClass(settings(this).extraClass);if(settings(this).fixPNG)helper.parent.fixPNG();handle.apply(this,arguments);}function show(){tID=null;if((!IE||!$.fn.bgiframe)&&settings(current).fade){if(helper.parent.is(":animated"))helper.parent.stop().show().fadeTo(settings(current).fade,current.tOpacity);else
helper.parent.is(':visible')?helper.parent.fadeTo(settings(current).fade,current.tOpacity):helper.parent.fadeIn(settings(current).fade);}else{helper.parent.show();}update();}function update(event){if($.tooltip.blocked)return;if(event&&event.target.tagName=="OPTION"){return;}if(!track&&helper.parent.is(":visible")){$(document.body).unbind('mousemove',update)}if(current==null){$(document.body).unbind('mousemove',update);return;}helper.parent.removeClass("viewport-right").removeClass("viewport-bottom");var left=helper.parent[0].offsetLeft;var top=helper.parent[0].offsetTop;if(event){left=event.pageX+settings(current).left;top=event.pageY+settings(current).top;var right='auto';if(settings(current).positionLeft){right=$(window).width()-left;left='auto';}helper.parent.css({left:left,right:right,top:top});}var v=viewport(),h=helper.parent[0];if(v.x+v.cx<h.offsetLeft+h.offsetWidth){left-=h.offsetWidth+20+settings(current).left;helper.parent.css({left:left+'px'}).addClass("viewport-right");}if(v.y+v.cy<h.offsetTop+h.offsetHeight){top-=h.offsetHeight+20+settings(current).top;helper.parent.css({top:top+'px'}).addClass("viewport-bottom");}}function viewport(){return{x:$(window).scrollLeft(),y:$(window).scrollTop(),cx:$(window).width(),cy:$(window).height()};}function hide(event){if($.tooltip.blocked)return;if(tID)clearTimeout(tID);current=null;var tsettings=settings(this);function complete(){helper.parent.removeClass(tsettings.extraClass).hide().css("opacity","");}if((!IE||!$.fn.bgiframe)&&tsettings.fade){if(helper.parent.is(':animated'))helper.parent.stop().fadeTo(tsettings.fade,0,complete);else
helper.parent.stop().fadeOut(tsettings.fade,complete);}else
complete();if(settings(this).fixPNG)helper.parent.unfixPNG();}})(jQuery);
